at v2.6.21 24 kB view raw
1/* 2 * class.c - basic device class management 3 * 4 * Copyright (c) 2002-3 Patrick Mochel 5 * Copyright (c) 2002-3 Open Source Development Labs 6 * Copyright (c) 2003-2004 Greg Kroah-Hartman 7 * Copyright (c) 2003-2004 IBM Corp. 8 * 9 * This file is released under the GPLv2 10 * 11 */ 12 13#include <linux/device.h> 14#include <linux/module.h> 15#include <linux/init.h> 16#include <linux/string.h> 17#include <linux/kdev_t.h> 18#include <linux/err.h> 19#include <linux/slab.h> 20#include "base.h" 21 22extern struct subsystem devices_subsys; 23 24#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) 25#define to_class(obj) container_of(obj, struct class, subsys.kset.kobj) 26 27static ssize_t 28class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) 29{ 30 struct class_attribute * class_attr = to_class_attr(attr); 31 struct class * dc = to_class(kobj); 32 ssize_t ret = -EIO; 33 34 if (class_attr->show) 35 ret = class_attr->show(dc, buf); 36 return ret; 37} 38 39static ssize_t 40class_attr_store(struct kobject * kobj, struct attribute * attr, 41 const char * buf, size_t count) 42{ 43 struct class_attribute * class_attr = to_class_attr(attr); 44 struct class * dc = to_class(kobj); 45 ssize_t ret = -EIO; 46 47 if (class_attr->store) 48 ret = class_attr->store(dc, buf, count); 49 return ret; 50} 51 52static void class_release(struct kobject * kobj) 53{ 54 struct class *class = to_class(kobj); 55 56 pr_debug("class '%s': release.\n", class->name); 57 58 if (class->class_release) 59 class->class_release(class); 60 else 61 pr_debug("class '%s' does not have a release() function, " 62 "be careful\n", class->name); 63} 64 65static struct sysfs_ops class_sysfs_ops = { 66 .show = class_attr_show, 67 .store = class_attr_store, 68}; 69 70static struct kobj_type ktype_class = { 71 .sysfs_ops = &class_sysfs_ops, 72 .release = class_release, 73}; 74 75/* Hotplug events for classes go to the class_obj subsys */ 76static decl_subsys(class, &ktype_class, NULL); 77 78 79int class_create_file(struct class * cls, const struct class_attribute * attr) 80{ 81 int error; 82 if (cls) { 83 error = sysfs_create_file(&cls->subsys.kset.kobj, &attr->attr); 84 } else 85 error = -EINVAL; 86 return error; 87} 88 89void class_remove_file(struct class * cls, const struct class_attribute * attr) 90{ 91 if (cls) 92 sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr); 93} 94 95static struct class *class_get(struct class *cls) 96{ 97 if (cls) 98 return container_of(subsys_get(&cls->subsys), struct class, subsys); 99 return NULL; 100} 101 102static void class_put(struct class * cls) 103{ 104 if (cls) 105 subsys_put(&cls->subsys); 106} 107 108 109static int add_class_attrs(struct class * cls) 110{ 111 int i; 112 int error = 0; 113 114 if (cls->class_attrs) { 115 for (i = 0; attr_name(cls->class_attrs[i]); i++) { 116 error = class_create_file(cls,&cls->class_attrs[i]); 117 if (error) 118 goto Err; 119 } 120 } 121 Done: 122 return error; 123 Err: 124 while (--i >= 0) 125 class_remove_file(cls,&cls->class_attrs[i]); 126 goto Done; 127} 128 129static void remove_class_attrs(struct class * cls) 130{ 131 int i; 132 133 if (cls->class_attrs) { 134 for (i = 0; attr_name(cls->class_attrs[i]); i++) 135 class_remove_file(cls,&cls->class_attrs[i]); 136 } 137} 138 139int class_register(struct class * cls) 140{ 141 int error; 142 143 pr_debug("device class '%s': registering\n", cls->name); 144 145 INIT_LIST_HEAD(&cls->children); 146 INIT_LIST_HEAD(&cls->devices); 147 INIT_LIST_HEAD(&cls->interfaces); 148 init_MUTEX(&cls->sem); 149 error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name); 150 if (error) 151 return error; 152 153 subsys_set_kset(cls, class_subsys); 154 155 error = subsystem_register(&cls->subsys); 156 if (!error) { 157 error = add_class_attrs(class_get(cls)); 158 class_put(cls); 159 } 160 return error; 161} 162 163void class_unregister(struct class * cls) 164{ 165 pr_debug("device class '%s': unregistering\n", cls->name); 166 kobject_unregister(cls->virtual_dir); 167 remove_class_attrs(cls); 168 subsystem_unregister(&cls->subsys); 169} 170 171static void class_create_release(struct class *cls) 172{ 173 pr_debug("%s called for %s\n", __FUNCTION__, cls->name); 174 kfree(cls); 175} 176 177static void class_device_create_release(struct class_device *class_dev) 178{ 179 pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id); 180 kfree(class_dev); 181} 182 183/* needed to allow these devices to have parent class devices */ 184static int class_device_create_uevent(struct class_device *class_dev, 185 char **envp, int num_envp, 186 char *buffer, int buffer_size) 187{ 188 pr_debug("%s called for %s\n", __FUNCTION__, class_dev->class_id); 189 return 0; 190} 191 192/** 193 * class_create - create a struct class structure 194 * @owner: pointer to the module that is to "own" this struct class 195 * @name: pointer to a string for the name of this class. 196 * 197 * This is used to create a struct class pointer that can then be used 198 * in calls to class_device_create(). 199 * 200 * Note, the pointer created here is to be destroyed when finished by 201 * making a call to class_destroy(). 202 */ 203struct class *class_create(struct module *owner, const char *name) 204{ 205 struct class *cls; 206 int retval; 207 208 cls = kzalloc(sizeof(*cls), GFP_KERNEL); 209 if (!cls) { 210 retval = -ENOMEM; 211 goto error; 212 } 213 214 cls->name = name; 215 cls->owner = owner; 216 cls->class_release = class_create_release; 217 cls->release = class_device_create_release; 218 219 retval = class_register(cls); 220 if (retval) 221 goto error; 222 223 return cls; 224 225error: 226 kfree(cls); 227 return ERR_PTR(retval); 228} 229 230/** 231 * class_destroy - destroys a struct class structure 232 * @cls: pointer to the struct class that is to be destroyed 233 * 234 * Note, the pointer to be destroyed must have been created with a call 235 * to class_create(). 236 */ 237void class_destroy(struct class *cls) 238{ 239 if ((cls == NULL) || (IS_ERR(cls))) 240 return; 241 242 class_unregister(cls); 243} 244 245/* Class Device Stuff */ 246 247int class_device_create_file(struct class_device * class_dev, 248 const struct class_device_attribute * attr) 249{ 250 int error = -EINVAL; 251 if (class_dev) 252 error = sysfs_create_file(&class_dev->kobj, &attr->attr); 253 return error; 254} 255 256void class_device_remove_file(struct class_device * class_dev, 257 const struct class_device_attribute * attr) 258{ 259 if (class_dev) 260 sysfs_remove_file(&class_dev->kobj, &attr->attr); 261} 262 263int class_device_create_bin_file(struct class_device *class_dev, 264 struct bin_attribute *attr) 265{ 266 int error = -EINVAL; 267 if (class_dev) 268 error = sysfs_create_bin_file(&class_dev->kobj, attr); 269 return error; 270} 271 272void class_device_remove_bin_file(struct class_device *class_dev, 273 struct bin_attribute *attr) 274{ 275 if (class_dev) 276 sysfs_remove_bin_file(&class_dev->kobj, attr); 277} 278 279static ssize_t 280class_device_attr_show(struct kobject * kobj, struct attribute * attr, 281 char * buf) 282{ 283 struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr); 284 struct class_device * cd = to_class_dev(kobj); 285 ssize_t ret = 0; 286 287 if (class_dev_attr->show) 288 ret = class_dev_attr->show(cd, buf); 289 return ret; 290} 291 292static ssize_t 293class_device_attr_store(struct kobject * kobj, struct attribute * attr, 294 const char * buf, size_t count) 295{ 296 struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr); 297 struct class_device * cd = to_class_dev(kobj); 298 ssize_t ret = 0; 299 300 if (class_dev_attr->store) 301 ret = class_dev_attr->store(cd, buf, count); 302 return ret; 303} 304 305static struct sysfs_ops class_dev_sysfs_ops = { 306 .show = class_device_attr_show, 307 .store = class_device_attr_store, 308}; 309 310static void class_dev_release(struct kobject * kobj) 311{ 312 struct class_device *cd = to_class_dev(kobj); 313 struct class * cls = cd->class; 314 315 pr_debug("device class '%s': release.\n", cd->class_id); 316 317 kfree(cd->devt_attr); 318 cd->devt_attr = NULL; 319 320 if (cd->release) 321 cd->release(cd); 322 else if (cls->release) 323 cls->release(cd); 324 else { 325 printk(KERN_ERR "Class Device '%s' does not have a release() function, " 326 "it is broken and must be fixed.\n", 327 cd->class_id); 328 WARN_ON(1); 329 } 330} 331 332static struct kobj_type ktype_class_device = { 333 .sysfs_ops = &class_dev_sysfs_ops, 334 .release = class_dev_release, 335}; 336 337static int class_uevent_filter(struct kset *kset, struct kobject *kobj) 338{ 339 struct kobj_type *ktype = get_ktype(kobj); 340 341 if (ktype == &ktype_class_device) { 342 struct class_device *class_dev = to_class_dev(kobj); 343 if (class_dev->class) 344 return 1; 345 } 346 return 0; 347} 348 349static const char *class_uevent_name(struct kset *kset, struct kobject *kobj) 350{ 351 struct class_device *class_dev = to_class_dev(kobj); 352 353 return class_dev->class->name; 354} 355 356#ifdef CONFIG_SYSFS_DEPRECATED 357char *make_class_name(const char *name, struct kobject *kobj) 358{ 359 char *class_name; 360 int size; 361 362 size = strlen(name) + strlen(kobject_name(kobj)) + 2; 363 364 class_name = kmalloc(size, GFP_KERNEL); 365 if (!class_name) 366 return NULL; 367 368 strcpy(class_name, name); 369 strcat(class_name, ":"); 370 strcat(class_name, kobject_name(kobj)); 371 return class_name; 372} 373 374static int deprecated_class_uevent(char **envp, int num_envp, int *cur_index, 375 char *buffer, int buffer_size, 376 int *cur_len, 377 struct class_device *class_dev) 378{ 379 struct device *dev = class_dev->dev; 380 char *path; 381 382 if (!dev) 383 return 0; 384 385 /* add device, backing this class device (deprecated) */ 386 path = kobject_get_path(&dev->kobj, GFP_KERNEL); 387 388 add_uevent_var(envp, num_envp, cur_index, buffer, buffer_size, 389 cur_len, "PHYSDEVPATH=%s", path); 390 kfree(path); 391 392 if (dev->bus) 393 add_uevent_var(envp, num_envp, cur_index, 394 buffer, buffer_size, cur_len, 395 "PHYSDEVBUS=%s", dev->bus->name); 396 397 if (dev->driver) 398 add_uevent_var(envp, num_envp, cur_index, 399 buffer, buffer_size, cur_len, 400 "PHYSDEVDRIVER=%s", dev->driver->name); 401 return 0; 402} 403 404static int make_deprecated_class_device_links(struct class_device *class_dev) 405{ 406 char *class_name; 407 int error; 408 409 if (!class_dev->dev) 410 return 0; 411 412 class_name = make_class_name(class_dev->class->name, &class_dev->kobj); 413 if (class_name) 414 error = sysfs_create_link(&class_dev->dev->kobj, 415 &class_dev->kobj, class_name); 416 else 417 error = -ENOMEM; 418 kfree(class_name); 419 return error; 420} 421 422static void remove_deprecated_class_device_links(struct class_device *class_dev) 423{ 424 char *class_name; 425 426 if (!class_dev->dev) 427 return; 428 429 class_name = make_class_name(class_dev->class->name, &class_dev->kobj); 430 if (class_name) 431 sysfs_remove_link(&class_dev->dev->kobj, class_name); 432 kfree(class_name); 433} 434#else 435static inline int deprecated_class_uevent(char **envp, int num_envp, 436 int *cur_index, char *buffer, 437 int buffer_size, int *cur_len, 438 struct class_device *class_dev) 439{ return 0; } 440static inline int make_deprecated_class_device_links(struct class_device *cd) 441{ return 0; } 442static void remove_deprecated_class_device_links(struct class_device *cd) 443{ } 444#endif 445 446static int class_uevent(struct kset *kset, struct kobject *kobj, char **envp, 447 int num_envp, char *buffer, int buffer_size) 448{ 449 struct class_device *class_dev = to_class_dev(kobj); 450 int i = 0; 451 int length = 0; 452 int retval = 0; 453 454 pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id); 455 456 deprecated_class_uevent(envp, num_envp, &i, buffer, buffer_size, 457 &length, class_dev); 458 459 if (MAJOR(class_dev->devt)) { 460 add_uevent_var(envp, num_envp, &i, 461 buffer, buffer_size, &length, 462 "MAJOR=%u", MAJOR(class_dev->devt)); 463 464 add_uevent_var(envp, num_envp, &i, 465 buffer, buffer_size, &length, 466 "MINOR=%u", MINOR(class_dev->devt)); 467 } 468 469 /* terminate, set to next free slot, shrink available space */ 470 envp[i] = NULL; 471 envp = &envp[i]; 472 num_envp -= i; 473 buffer = &buffer[length]; 474 buffer_size -= length; 475 476 if (class_dev->uevent) { 477 /* have the class device specific function add its stuff */ 478 retval = class_dev->uevent(class_dev, envp, num_envp, 479 buffer, buffer_size); 480 if (retval) 481 pr_debug("class_dev->uevent() returned %d\n", retval); 482 } else if (class_dev->class->uevent) { 483 /* have the class specific function add its stuff */ 484 retval = class_dev->class->uevent(class_dev, envp, num_envp, 485 buffer, buffer_size); 486 if (retval) 487 pr_debug("class->uevent() returned %d\n", retval); 488 } 489 490 return retval; 491} 492 493static struct kset_uevent_ops class_uevent_ops = { 494 .filter = class_uevent_filter, 495 .name = class_uevent_name, 496 .uevent = class_uevent, 497}; 498 499static decl_subsys(class_obj, &ktype_class_device, &class_uevent_ops); 500 501 502static int class_device_add_attrs(struct class_device * cd) 503{ 504 int i; 505 int error = 0; 506 struct class * cls = cd->class; 507 508 if (cls->class_dev_attrs) { 509 for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) { 510 error = class_device_create_file(cd, 511 &cls->class_dev_attrs[i]); 512 if (error) 513 goto Err; 514 } 515 } 516 Done: 517 return error; 518 Err: 519 while (--i >= 0) 520 class_device_remove_file(cd,&cls->class_dev_attrs[i]); 521 goto Done; 522} 523 524static void class_device_remove_attrs(struct class_device * cd) 525{ 526 int i; 527 struct class * cls = cd->class; 528 529 if (cls->class_dev_attrs) { 530 for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) 531 class_device_remove_file(cd,&cls->class_dev_attrs[i]); 532 } 533} 534 535static int class_device_add_groups(struct class_device * cd) 536{ 537 int i; 538 int error = 0; 539 540 if (cd->groups) { 541 for (i = 0; cd->groups[i]; i++) { 542 error = sysfs_create_group(&cd->kobj, cd->groups[i]); 543 if (error) { 544 while (--i >= 0) 545 sysfs_remove_group(&cd->kobj, cd->groups[i]); 546 goto out; 547 } 548 } 549 } 550out: 551 return error; 552} 553 554static void class_device_remove_groups(struct class_device * cd) 555{ 556 int i; 557 if (cd->groups) { 558 for (i = 0; cd->groups[i]; i++) { 559 sysfs_remove_group(&cd->kobj, cd->groups[i]); 560 } 561 } 562} 563 564static ssize_t show_dev(struct class_device *class_dev, char *buf) 565{ 566 return print_dev_t(buf, class_dev->devt); 567} 568 569static ssize_t store_uevent(struct class_device *class_dev, 570 const char *buf, size_t count) 571{ 572 kobject_uevent(&class_dev->kobj, KOBJ_ADD); 573 return count; 574} 575 576void class_device_initialize(struct class_device *class_dev) 577{ 578 kobj_set_kset_s(class_dev, class_obj_subsys); 579 kobject_init(&class_dev->kobj); 580 INIT_LIST_HEAD(&class_dev->node); 581} 582 583int class_device_add(struct class_device *class_dev) 584{ 585 struct class *parent_class = NULL; 586 struct class_device *parent_class_dev = NULL; 587 struct class_interface *class_intf; 588 int error = -EINVAL; 589 590 class_dev = class_device_get(class_dev); 591 if (!class_dev) 592 return -EINVAL; 593 594 if (!strlen(class_dev->class_id)) 595 goto out1; 596 597 parent_class = class_get(class_dev->class); 598 if (!parent_class) 599 goto out1; 600 601 parent_class_dev = class_device_get(class_dev->parent); 602 603 pr_debug("CLASS: registering class device: ID = '%s'\n", 604 class_dev->class_id); 605 606 /* first, register with generic layer. */ 607 error = kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id); 608 if (error) 609 goto out2; 610 611 if (parent_class_dev) 612 class_dev->kobj.parent = &parent_class_dev->kobj; 613 else 614 class_dev->kobj.parent = &parent_class->subsys.kset.kobj; 615 616 error = kobject_add(&class_dev->kobj); 617 if (error) 618 goto out2; 619 620 /* add the needed attributes to this device */ 621 error = sysfs_create_link(&class_dev->kobj, 622 &parent_class->subsys.kset.kobj, "subsystem"); 623 if (error) 624 goto out3; 625 class_dev->uevent_attr.attr.name = "uevent"; 626 class_dev->uevent_attr.attr.mode = S_IWUSR; 627 class_dev->uevent_attr.attr.owner = parent_class->owner; 628 class_dev->uevent_attr.store = store_uevent; 629 error = class_device_create_file(class_dev, &class_dev->uevent_attr); 630 if (error) 631 goto out3; 632 633 if (MAJOR(class_dev->devt)) { 634 struct class_device_attribute *attr; 635 attr = kzalloc(sizeof(*attr), GFP_KERNEL); 636 if (!attr) { 637 error = -ENOMEM; 638 goto out4; 639 } 640 attr->attr.name = "dev"; 641 attr->attr.mode = S_IRUGO; 642 attr->attr.owner = parent_class->owner; 643 attr->show = show_dev; 644 error = class_device_create_file(class_dev, attr); 645 if (error) { 646 kfree(attr); 647 goto out4; 648 } 649 650 class_dev->devt_attr = attr; 651 } 652 653 error = class_device_add_attrs(class_dev); 654 if (error) 655 goto out5; 656 657 if (class_dev->dev) { 658 error = sysfs_create_link(&class_dev->kobj, 659 &class_dev->dev->kobj, "device"); 660 if (error) 661 goto out6; 662 } 663 664 error = class_device_add_groups(class_dev); 665 if (error) 666 goto out7; 667 668 error = make_deprecated_class_device_links(class_dev); 669 if (error) 670 goto out8; 671 672 kobject_uevent(&class_dev->kobj, KOBJ_ADD); 673 674 /* notify any interfaces this device is now here */ 675 down(&parent_class->sem); 676 list_add_tail(&class_dev->node, &parent_class->children); 677 list_for_each_entry(class_intf, &parent_class->interfaces, node) { 678 if (class_intf->add) 679 class_intf->add(class_dev, class_intf); 680 } 681 up(&parent_class->sem); 682 683 goto out1; 684 685 out8: 686 class_device_remove_groups(class_dev); 687 out7: 688 if (class_dev->dev) 689 sysfs_remove_link(&class_dev->kobj, "device"); 690 out6: 691 class_device_remove_attrs(class_dev); 692 out5: 693 if (class_dev->devt_attr) 694 class_device_remove_file(class_dev, class_dev->devt_attr); 695 out4: 696 class_device_remove_file(class_dev, &class_dev->uevent_attr); 697 out3: 698 kobject_del(&class_dev->kobj); 699 out2: 700 if(parent_class_dev) 701 class_device_put(parent_class_dev); 702 class_put(parent_class); 703 out1: 704 class_device_put(class_dev); 705 return error; 706} 707 708int class_device_register(struct class_device *class_dev) 709{ 710 class_device_initialize(class_dev); 711 return class_device_add(class_dev); 712} 713 714/** 715 * class_device_create - creates a class device and registers it with sysfs 716 * @cls: pointer to the struct class that this device should be registered to. 717 * @parent: pointer to the parent struct class_device of this new device, if any. 718 * @devt: the dev_t for the char device to be added. 719 * @device: a pointer to a struct device that is assiociated with this class device. 720 * @fmt: string for the class device's name 721 * 722 * This function can be used by char device classes. A struct 723 * class_device will be created in sysfs, registered to the specified 724 * class. 725 * A "dev" file will be created, showing the dev_t for the device, if 726 * the dev_t is not 0,0. 727 * If a pointer to a parent struct class_device is passed in, the newly 728 * created struct class_device will be a child of that device in sysfs. 729 * The pointer to the struct class_device will be returned from the 730 * call. Any further sysfs files that might be required can be created 731 * using this pointer. 732 * 733 * Note: the struct class passed to this function must have previously 734 * been created with a call to class_create(). 735 */ 736struct class_device *class_device_create(struct class *cls, 737 struct class_device *parent, 738 dev_t devt, 739 struct device *device, 740 const char *fmt, ...) 741{ 742 va_list args; 743 struct class_device *class_dev = NULL; 744 int retval = -ENODEV; 745 746 if (cls == NULL || IS_ERR(cls)) 747 goto error; 748 749 class_dev = kzalloc(sizeof(*class_dev), GFP_KERNEL); 750 if (!class_dev) { 751 retval = -ENOMEM; 752 goto error; 753 } 754 755 class_dev->devt = devt; 756 class_dev->dev = device; 757 class_dev->class = cls; 758 class_dev->parent = parent; 759 class_dev->release = class_device_create_release; 760 class_dev->uevent = class_device_create_uevent; 761 762 va_start(args, fmt); 763 vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args); 764 va_end(args); 765 retval = class_device_register(class_dev); 766 if (retval) 767 goto error; 768 769 return class_dev; 770 771error: 772 kfree(class_dev); 773 return ERR_PTR(retval); 774} 775 776void class_device_del(struct class_device *class_dev) 777{ 778 struct class *parent_class = class_dev->class; 779 struct class_device *parent_device = class_dev->parent; 780 struct class_interface *class_intf; 781 782 if (parent_class) { 783 down(&parent_class->sem); 784 list_del_init(&class_dev->node); 785 list_for_each_entry(class_intf, &parent_class->interfaces, node) 786 if (class_intf->remove) 787 class_intf->remove(class_dev, class_intf); 788 up(&parent_class->sem); 789 } 790 791 if (class_dev->dev) { 792 remove_deprecated_class_device_links(class_dev); 793 sysfs_remove_link(&class_dev->kobj, "device"); 794 } 795 sysfs_remove_link(&class_dev->kobj, "subsystem"); 796 class_device_remove_file(class_dev, &class_dev->uevent_attr); 797 if (class_dev->devt_attr) 798 class_device_remove_file(class_dev, class_dev->devt_attr); 799 class_device_remove_attrs(class_dev); 800 class_device_remove_groups(class_dev); 801 802 kobject_uevent(&class_dev->kobj, KOBJ_REMOVE); 803 kobject_del(&class_dev->kobj); 804 805 class_device_put(parent_device); 806 class_put(parent_class); 807} 808 809void class_device_unregister(struct class_device *class_dev) 810{ 811 pr_debug("CLASS: Unregistering class device. ID = '%s'\n", 812 class_dev->class_id); 813 class_device_del(class_dev); 814 class_device_put(class_dev); 815} 816 817/** 818 * class_device_destroy - removes a class device that was created with class_device_create() 819 * @cls: the pointer to the struct class that this device was registered * with. 820 * @devt: the dev_t of the device that was previously registered. 821 * 822 * This call unregisters and cleans up a class device that was created with a 823 * call to class_device_create() 824 */ 825void class_device_destroy(struct class *cls, dev_t devt) 826{ 827 struct class_device *class_dev = NULL; 828 struct class_device *class_dev_tmp; 829 830 down(&cls->sem); 831 list_for_each_entry(class_dev_tmp, &cls->children, node) { 832 if (class_dev_tmp->devt == devt) { 833 class_dev = class_dev_tmp; 834 break; 835 } 836 } 837 up(&cls->sem); 838 839 if (class_dev) 840 class_device_unregister(class_dev); 841} 842 843struct class_device * class_device_get(struct class_device *class_dev) 844{ 845 if (class_dev) 846 return to_class_dev(kobject_get(&class_dev->kobj)); 847 return NULL; 848} 849 850void class_device_put(struct class_device *class_dev) 851{ 852 if (class_dev) 853 kobject_put(&class_dev->kobj); 854} 855 856 857int class_interface_register(struct class_interface *class_intf) 858{ 859 struct class *parent; 860 struct class_device *class_dev; 861 struct device *dev; 862 863 if (!class_intf || !class_intf->class) 864 return -ENODEV; 865 866 parent = class_get(class_intf->class); 867 if (!parent) 868 return -EINVAL; 869 870 down(&parent->sem); 871 list_add_tail(&class_intf->node, &parent->interfaces); 872 if (class_intf->add) { 873 list_for_each_entry(class_dev, &parent->children, node) 874 class_intf->add(class_dev, class_intf); 875 } 876 if (class_intf->add_dev) { 877 list_for_each_entry(dev, &parent->devices, node) 878 class_intf->add_dev(dev, class_intf); 879 } 880 up(&parent->sem); 881 882 return 0; 883} 884 885void class_interface_unregister(struct class_interface *class_intf) 886{ 887 struct class * parent = class_intf->class; 888 struct class_device *class_dev; 889 struct device *dev; 890 891 if (!parent) 892 return; 893 894 down(&parent->sem); 895 list_del_init(&class_intf->node); 896 if (class_intf->remove) { 897 list_for_each_entry(class_dev, &parent->children, node) 898 class_intf->remove(class_dev, class_intf); 899 } 900 if (class_intf->remove_dev) { 901 list_for_each_entry(dev, &parent->devices, node) 902 class_intf->remove_dev(dev, class_intf); 903 } 904 up(&parent->sem); 905 906 class_put(parent); 907} 908 909int __init classes_init(void) 910{ 911 int retval; 912 913 retval = subsystem_register(&class_subsys); 914 if (retval) 915 return retval; 916 917 /* ick, this is ugly, the things we go through to keep from showing up 918 * in sysfs... */ 919 subsystem_init(&class_obj_subsys); 920 if (!class_obj_subsys.kset.subsys) 921 class_obj_subsys.kset.subsys = &class_obj_subsys; 922 return 0; 923} 924 925EXPORT_SYMBOL_GPL(class_create_file); 926EXPORT_SYMBOL_GPL(class_remove_file); 927EXPORT_SYMBOL_GPL(class_register); 928EXPORT_SYMBOL_GPL(class_unregister); 929EXPORT_SYMBOL_GPL(class_create); 930EXPORT_SYMBOL_GPL(class_destroy); 931 932EXPORT_SYMBOL_GPL(class_device_register); 933EXPORT_SYMBOL_GPL(class_device_unregister); 934EXPORT_SYMBOL_GPL(class_device_initialize); 935EXPORT_SYMBOL_GPL(class_device_add); 936EXPORT_SYMBOL_GPL(class_device_del); 937EXPORT_SYMBOL_GPL(class_device_get); 938EXPORT_SYMBOL_GPL(class_device_put); 939EXPORT_SYMBOL_GPL(class_device_create); 940EXPORT_SYMBOL_GPL(class_device_destroy); 941EXPORT_SYMBOL_GPL(class_device_create_file); 942EXPORT_SYMBOL_GPL(class_device_remove_file); 943EXPORT_SYMBOL_GPL(class_device_create_bin_file); 944EXPORT_SYMBOL_GPL(class_device_remove_bin_file); 945 946EXPORT_SYMBOL_GPL(class_interface_register); 947EXPORT_SYMBOL_GPL(class_interface_unregister);