class.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  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. #include <linux/config.h>
  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 "base.h"
  20. #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
  21. #define to_class(obj) container_of(obj, struct class, subsys.kset.kobj)
  22. static ssize_t
  23. class_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
  24. {
  25. struct class_attribute * class_attr = to_class_attr(attr);
  26. struct class * dc = to_class(kobj);
  27. ssize_t ret = -EIO;
  28. if (class_attr->show)
  29. ret = class_attr->show(dc, buf);
  30. return ret;
  31. }
  32. static ssize_t
  33. class_attr_store(struct kobject * kobj, struct attribute * attr,
  34. const char * buf, size_t count)
  35. {
  36. struct class_attribute * class_attr = to_class_attr(attr);
  37. struct class * dc = to_class(kobj);
  38. ssize_t ret = -EIO;
  39. if (class_attr->store)
  40. ret = class_attr->store(dc, buf, count);
  41. return ret;
  42. }
  43. static void class_release(struct kobject * kobj)
  44. {
  45. struct class *class = to_class(kobj);
  46. pr_debug("class '%s': release.\n", class->name);
  47. if (class->class_release)
  48. class->class_release(class);
  49. else
  50. pr_debug("class '%s' does not have a release() function, "
  51. "be careful\n", class->name);
  52. }
  53. static struct sysfs_ops class_sysfs_ops = {
  54. .show = class_attr_show,
  55. .store = class_attr_store,
  56. };
  57. static struct kobj_type ktype_class = {
  58. .sysfs_ops = &class_sysfs_ops,
  59. .release = class_release,
  60. };
  61. /* Hotplug events for classes go to the class_obj subsys */
  62. static decl_subsys(class, &ktype_class, NULL);
  63. int class_create_file(struct class * cls, const struct class_attribute * attr)
  64. {
  65. int error;
  66. if (cls) {
  67. error = sysfs_create_file(&cls->subsys.kset.kobj, &attr->attr);
  68. } else
  69. error = -EINVAL;
  70. return error;
  71. }
  72. void class_remove_file(struct class * cls, const struct class_attribute * attr)
  73. {
  74. if (cls)
  75. sysfs_remove_file(&cls->subsys.kset.kobj, &attr->attr);
  76. }
  77. struct class * class_get(struct class * cls)
  78. {
  79. if (cls)
  80. return container_of(subsys_get(&cls->subsys), struct class, subsys);
  81. return NULL;
  82. }
  83. void class_put(struct class * cls)
  84. {
  85. subsys_put(&cls->subsys);
  86. }
  87. static int add_class_attrs(struct class * cls)
  88. {
  89. int i;
  90. int error = 0;
  91. if (cls->class_attrs) {
  92. for (i = 0; attr_name(cls->class_attrs[i]); i++) {
  93. error = class_create_file(cls,&cls->class_attrs[i]);
  94. if (error)
  95. goto Err;
  96. }
  97. }
  98. Done:
  99. return error;
  100. Err:
  101. while (--i >= 0)
  102. class_remove_file(cls,&cls->class_attrs[i]);
  103. goto Done;
  104. }
  105. static void remove_class_attrs(struct class * cls)
  106. {
  107. int i;
  108. if (cls->class_attrs) {
  109. for (i = 0; attr_name(cls->class_attrs[i]); i++)
  110. class_remove_file(cls,&cls->class_attrs[i]);
  111. }
  112. }
  113. int class_register(struct class * cls)
  114. {
  115. int error;
  116. pr_debug("device class '%s': registering\n", cls->name);
  117. INIT_LIST_HEAD(&cls->children);
  118. INIT_LIST_HEAD(&cls->interfaces);
  119. init_MUTEX(&cls->sem);
  120. error = kobject_set_name(&cls->subsys.kset.kobj, "%s", cls->name);
  121. if (error)
  122. return error;
  123. subsys_set_kset(cls, class_subsys);
  124. error = subsystem_register(&cls->subsys);
  125. if (!error) {
  126. error = add_class_attrs(class_get(cls));
  127. class_put(cls);
  128. }
  129. return error;
  130. }
  131. void class_unregister(struct class * cls)
  132. {
  133. pr_debug("device class '%s': unregistering\n", cls->name);
  134. remove_class_attrs(cls);
  135. subsystem_unregister(&cls->subsys);
  136. }
  137. static void class_create_release(struct class *cls)
  138. {
  139. kfree(cls);
  140. }
  141. static void class_device_create_release(struct class_device *class_dev)
  142. {
  143. kfree(class_dev);
  144. }
  145. /**
  146. * class_create - create a struct class structure
  147. * @owner: pointer to the module that is to "own" this struct class
  148. * @name: pointer to a string for the name of this class.
  149. *
  150. * This is used to create a struct class pointer that can then be used
  151. * in calls to class_device_create().
  152. *
  153. * Note, the pointer created here is to be destroyed when finished by
  154. * making a call to class_destroy().
  155. */
  156. struct class *class_create(struct module *owner, char *name)
  157. {
  158. struct class *cls;
  159. int retval;
  160. cls = kmalloc(sizeof(struct class), GFP_KERNEL);
  161. if (!cls) {
  162. retval = -ENOMEM;
  163. goto error;
  164. }
  165. memset(cls, 0x00, sizeof(struct class));
  166. cls->name = name;
  167. cls->owner = owner;
  168. cls->class_release = class_create_release;
  169. cls->release = class_device_create_release;
  170. retval = class_register(cls);
  171. if (retval)
  172. goto error;
  173. return cls;
  174. error:
  175. kfree(cls);
  176. return ERR_PTR(retval);
  177. }
  178. /**
  179. * class_destroy - destroys a struct class structure
  180. * @cs: pointer to the struct class that is to be destroyed
  181. *
  182. * Note, the pointer to be destroyed must have been created with a call
  183. * to class_create().
  184. */
  185. void class_destroy(struct class *cls)
  186. {
  187. if ((cls == NULL) || (IS_ERR(cls)))
  188. return;
  189. class_unregister(cls);
  190. }
  191. /* Class Device Stuff */
  192. int class_device_create_file(struct class_device * class_dev,
  193. const struct class_device_attribute * attr)
  194. {
  195. int error = -EINVAL;
  196. if (class_dev)
  197. error = sysfs_create_file(&class_dev->kobj, &attr->attr);
  198. return error;
  199. }
  200. void class_device_remove_file(struct class_device * class_dev,
  201. const struct class_device_attribute * attr)
  202. {
  203. if (class_dev)
  204. sysfs_remove_file(&class_dev->kobj, &attr->attr);
  205. }
  206. int class_device_create_bin_file(struct class_device *class_dev,
  207. struct bin_attribute *attr)
  208. {
  209. int error = -EINVAL;
  210. if (class_dev)
  211. error = sysfs_create_bin_file(&class_dev->kobj, attr);
  212. return error;
  213. }
  214. void class_device_remove_bin_file(struct class_device *class_dev,
  215. struct bin_attribute *attr)
  216. {
  217. if (class_dev)
  218. sysfs_remove_bin_file(&class_dev->kobj, attr);
  219. }
  220. static ssize_t
  221. class_device_attr_show(struct kobject * kobj, struct attribute * attr,
  222. char * buf)
  223. {
  224. struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
  225. struct class_device * cd = to_class_dev(kobj);
  226. ssize_t ret = 0;
  227. if (class_dev_attr->show)
  228. ret = class_dev_attr->show(cd, buf);
  229. return ret;
  230. }
  231. static ssize_t
  232. class_device_attr_store(struct kobject * kobj, struct attribute * attr,
  233. const char * buf, size_t count)
  234. {
  235. struct class_device_attribute * class_dev_attr = to_class_dev_attr(attr);
  236. struct class_device * cd = to_class_dev(kobj);
  237. ssize_t ret = 0;
  238. if (class_dev_attr->store)
  239. ret = class_dev_attr->store(cd, buf, count);
  240. return ret;
  241. }
  242. static struct sysfs_ops class_dev_sysfs_ops = {
  243. .show = class_device_attr_show,
  244. .store = class_device_attr_store,
  245. };
  246. static void class_dev_release(struct kobject * kobj)
  247. {
  248. struct class_device *cd = to_class_dev(kobj);
  249. struct class * cls = cd->class;
  250. pr_debug("device class '%s': release.\n", cd->class_id);
  251. if (cls->release)
  252. cls->release(cd);
  253. else {
  254. printk(KERN_ERR "Device class '%s' does not have a release() function, "
  255. "it is broken and must be fixed.\n",
  256. cd->class_id);
  257. WARN_ON(1);
  258. }
  259. }
  260. static struct kobj_type ktype_class_device = {
  261. .sysfs_ops = &class_dev_sysfs_ops,
  262. .release = class_dev_release,
  263. };
  264. static int class_hotplug_filter(struct kset *kset, struct kobject *kobj)
  265. {
  266. struct kobj_type *ktype = get_ktype(kobj);
  267. if (ktype == &ktype_class_device) {
  268. struct class_device *class_dev = to_class_dev(kobj);
  269. if (class_dev->class)
  270. return 1;
  271. }
  272. return 0;
  273. }
  274. static const char *class_hotplug_name(struct kset *kset, struct kobject *kobj)
  275. {
  276. struct class_device *class_dev = to_class_dev(kobj);
  277. return class_dev->class->name;
  278. }
  279. static int class_hotplug(struct kset *kset, struct kobject *kobj, char **envp,
  280. int num_envp, char *buffer, int buffer_size)
  281. {
  282. struct class_device *class_dev = to_class_dev(kobj);
  283. int i = 0;
  284. int length = 0;
  285. int retval = 0;
  286. pr_debug("%s - name = %s\n", __FUNCTION__, class_dev->class_id);
  287. if (class_dev->dev) {
  288. /* add physical device, backing this device */
  289. struct device *dev = class_dev->dev;
  290. char *path = kobject_get_path(&dev->kobj, GFP_KERNEL);
  291. add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size,
  292. &length, "PHYSDEVPATH=%s", path);
  293. kfree(path);
  294. if (dev->bus)
  295. add_hotplug_env_var(envp, num_envp, &i,
  296. buffer, buffer_size, &length,
  297. "PHYSDEVBUS=%s", dev->bus->name);
  298. if (dev->driver)
  299. add_hotplug_env_var(envp, num_envp, &i,
  300. buffer, buffer_size, &length,
  301. "PHYSDEVDRIVER=%s", dev->driver->name);
  302. }
  303. if (MAJOR(class_dev->devt)) {
  304. add_hotplug_env_var(envp, num_envp, &i,
  305. buffer, buffer_size, &length,
  306. "MAJOR=%u", MAJOR(class_dev->devt));
  307. add_hotplug_env_var(envp, num_envp, &i,
  308. buffer, buffer_size, &length,
  309. "MINOR=%u", MINOR(class_dev->devt));
  310. }
  311. /* terminate, set to next free slot, shrink available space */
  312. envp[i] = NULL;
  313. envp = &envp[i];
  314. num_envp -= i;
  315. buffer = &buffer[length];
  316. buffer_size -= length;
  317. if (class_dev->class->hotplug) {
  318. /* have the bus specific function add its stuff */
  319. retval = class_dev->class->hotplug (class_dev, envp, num_envp,
  320. buffer, buffer_size);
  321. if (retval) {
  322. pr_debug ("%s - hotplug() returned %d\n",
  323. __FUNCTION__, retval);
  324. }
  325. }
  326. return retval;
  327. }
  328. static struct kset_hotplug_ops class_hotplug_ops = {
  329. .filter = class_hotplug_filter,
  330. .name = class_hotplug_name,
  331. .hotplug = class_hotplug,
  332. };
  333. static decl_subsys(class_obj, &ktype_class_device, &class_hotplug_ops);
  334. static int class_device_add_attrs(struct class_device * cd)
  335. {
  336. int i;
  337. int error = 0;
  338. struct class * cls = cd->class;
  339. if (cls->class_dev_attrs) {
  340. for (i = 0; attr_name(cls->class_dev_attrs[i]); i++) {
  341. error = class_device_create_file(cd,
  342. &cls->class_dev_attrs[i]);
  343. if (error)
  344. goto Err;
  345. }
  346. }
  347. Done:
  348. return error;
  349. Err:
  350. while (--i >= 0)
  351. class_device_remove_file(cd,&cls->class_dev_attrs[i]);
  352. goto Done;
  353. }
  354. static void class_device_remove_attrs(struct class_device * cd)
  355. {
  356. int i;
  357. struct class * cls = cd->class;
  358. if (cls->class_dev_attrs) {
  359. for (i = 0; attr_name(cls->class_dev_attrs[i]); i++)
  360. class_device_remove_file(cd,&cls->class_dev_attrs[i]);
  361. }
  362. }
  363. static ssize_t show_dev(struct class_device *class_dev, char *buf)
  364. {
  365. return print_dev_t(buf, class_dev->devt);
  366. }
  367. void class_device_initialize(struct class_device *class_dev)
  368. {
  369. kobj_set_kset_s(class_dev, class_obj_subsys);
  370. kobject_init(&class_dev->kobj);
  371. INIT_LIST_HEAD(&class_dev->node);
  372. }
  373. int class_device_add(struct class_device *class_dev)
  374. {
  375. struct class * parent = NULL;
  376. struct class_interface * class_intf;
  377. int error;
  378. class_dev = class_device_get(class_dev);
  379. if (!class_dev)
  380. return -EINVAL;
  381. if (!strlen(class_dev->class_id)) {
  382. error = -EINVAL;
  383. goto register_done;
  384. }
  385. parent = class_get(class_dev->class);
  386. pr_debug("CLASS: registering class device: ID = '%s'\n",
  387. class_dev->class_id);
  388. /* first, register with generic layer. */
  389. kobject_set_name(&class_dev->kobj, "%s", class_dev->class_id);
  390. if (parent)
  391. class_dev->kobj.parent = &parent->subsys.kset.kobj;
  392. if ((error = kobject_add(&class_dev->kobj)))
  393. goto register_done;
  394. /* add the needed attributes to this device */
  395. if (MAJOR(class_dev->devt)) {
  396. struct class_device_attribute *attr;
  397. attr = kmalloc(sizeof(*attr), GFP_KERNEL);
  398. if (!attr) {
  399. error = -ENOMEM;
  400. kobject_del(&class_dev->kobj);
  401. goto register_done;
  402. }
  403. memset(attr, sizeof(*attr), 0x00);
  404. attr->attr.name = "dev";
  405. attr->attr.mode = S_IRUGO;
  406. attr->attr.owner = parent->owner;
  407. attr->show = show_dev;
  408. attr->store = NULL;
  409. class_device_create_file(class_dev, attr);
  410. class_dev->devt_attr = attr;
  411. }
  412. class_device_add_attrs(class_dev);
  413. if (class_dev->dev)
  414. sysfs_create_link(&class_dev->kobj,
  415. &class_dev->dev->kobj, "device");
  416. /* notify any interfaces this device is now here */
  417. if (parent) {
  418. down(&parent->sem);
  419. list_add_tail(&class_dev->node, &parent->children);
  420. list_for_each_entry(class_intf, &parent->interfaces, node)
  421. if (class_intf->add)
  422. class_intf->add(class_dev);
  423. up(&parent->sem);
  424. }
  425. kobject_hotplug(&class_dev->kobj, KOBJ_ADD);
  426. register_done:
  427. if (error && parent)
  428. class_put(parent);
  429. class_device_put(class_dev);
  430. return error;
  431. }
  432. int class_device_register(struct class_device *class_dev)
  433. {
  434. class_device_initialize(class_dev);
  435. return class_device_add(class_dev);
  436. }
  437. /**
  438. * class_device_create - creates a class device and registers it with sysfs
  439. * @cs: pointer to the struct class that this device should be registered to.
  440. * @dev: the dev_t for the char device to be added.
  441. * @device: a pointer to a struct device that is assiociated with this class device.
  442. * @fmt: string for the class device's name
  443. *
  444. * This function can be used by char device classes. A struct
  445. * class_device will be created in sysfs, registered to the specified
  446. * class. A "dev" file will be created, showing the dev_t for the
  447. * device. The pointer to the struct class_device will be returned from
  448. * the call. Any further sysfs files that might be required can be
  449. * created using this pointer.
  450. *
  451. * Note: the struct class passed to this function must have previously
  452. * been created with a call to class_create().
  453. */
  454. struct class_device *class_device_create(struct class *cls, dev_t devt,
  455. struct device *device, char *fmt, ...)
  456. {
  457. va_list args;
  458. struct class_device *class_dev = NULL;
  459. int retval = -ENODEV;
  460. if (cls == NULL || IS_ERR(cls))
  461. goto error;
  462. class_dev = kmalloc(sizeof(struct class_device), GFP_KERNEL);
  463. if (!class_dev) {
  464. retval = -ENOMEM;
  465. goto error;
  466. }
  467. memset(class_dev, 0x00, sizeof(struct class_device));
  468. class_dev->devt = devt;
  469. class_dev->dev = device;
  470. class_dev->class = cls;
  471. va_start(args, fmt);
  472. vsnprintf(class_dev->class_id, BUS_ID_SIZE, fmt, args);
  473. va_end(args);
  474. retval = class_device_register(class_dev);
  475. if (retval)
  476. goto error;
  477. return class_dev;
  478. error:
  479. kfree(class_dev);
  480. return ERR_PTR(retval);
  481. }
  482. void class_device_del(struct class_device *class_dev)
  483. {
  484. struct class * parent = class_dev->class;
  485. struct class_interface * class_intf;
  486. if (parent) {
  487. down(&parent->sem);
  488. list_del_init(&class_dev->node);
  489. list_for_each_entry(class_intf, &parent->interfaces, node)
  490. if (class_intf->remove)
  491. class_intf->remove(class_dev);
  492. up(&parent->sem);
  493. }
  494. if (class_dev->dev)
  495. sysfs_remove_link(&class_dev->kobj, "device");
  496. if (class_dev->devt_attr) {
  497. class_device_remove_file(class_dev, class_dev->devt_attr);
  498. kfree(class_dev->devt_attr);
  499. class_dev->devt_attr = NULL;
  500. }
  501. class_device_remove_attrs(class_dev);
  502. kobject_hotplug(&class_dev->kobj, KOBJ_REMOVE);
  503. kobject_del(&class_dev->kobj);
  504. if (parent)
  505. class_put(parent);
  506. }
  507. void class_device_unregister(struct class_device *class_dev)
  508. {
  509. pr_debug("CLASS: Unregistering class device. ID = '%s'\n",
  510. class_dev->class_id);
  511. class_device_del(class_dev);
  512. class_device_put(class_dev);
  513. }
  514. /**
  515. * class_device_destroy - removes a class device that was created with class_device_create()
  516. * @cls: the pointer to the struct class that this device was registered * with.
  517. * @dev: the dev_t of the device that was previously registered.
  518. *
  519. * This call unregisters and cleans up a class device that was created with a
  520. * call to class_device_create()
  521. */
  522. void class_device_destroy(struct class *cls, dev_t devt)
  523. {
  524. struct class_device *class_dev = NULL;
  525. struct class_device *class_dev_tmp;
  526. down(&cls->sem);
  527. list_for_each_entry(class_dev_tmp, &cls->children, node) {
  528. if (class_dev_tmp->devt == devt) {
  529. class_dev = class_dev_tmp;
  530. break;
  531. }
  532. }
  533. up(&cls->sem);
  534. if (class_dev)
  535. class_device_unregister(class_dev);
  536. }
  537. int class_device_rename(struct class_device *class_dev, char *new_name)
  538. {
  539. int error = 0;
  540. class_dev = class_device_get(class_dev);
  541. if (!class_dev)
  542. return -EINVAL;
  543. pr_debug("CLASS: renaming '%s' to '%s'\n", class_dev->class_id,
  544. new_name);
  545. strlcpy(class_dev->class_id, new_name, KOBJ_NAME_LEN);
  546. error = kobject_rename(&class_dev->kobj, new_name);
  547. class_device_put(class_dev);
  548. return error;
  549. }
  550. struct class_device * class_device_get(struct class_device *class_dev)
  551. {
  552. if (class_dev)
  553. return to_class_dev(kobject_get(&class_dev->kobj));
  554. return NULL;
  555. }
  556. void class_device_put(struct class_device *class_dev)
  557. {
  558. kobject_put(&class_dev->kobj);
  559. }
  560. int class_interface_register(struct class_interface *class_intf)
  561. {
  562. struct class *parent;
  563. struct class_device *class_dev;
  564. if (!class_intf || !class_intf->class)
  565. return -ENODEV;
  566. parent = class_get(class_intf->class);
  567. if (!parent)
  568. return -EINVAL;
  569. down(&parent->sem);
  570. list_add_tail(&class_intf->node, &parent->interfaces);
  571. if (class_intf->add) {
  572. list_for_each_entry(class_dev, &parent->children, node)
  573. class_intf->add(class_dev);
  574. }
  575. up(&parent->sem);
  576. return 0;
  577. }
  578. void class_interface_unregister(struct class_interface *class_intf)
  579. {
  580. struct class * parent = class_intf->class;
  581. struct class_device *class_dev;
  582. if (!parent)
  583. return;
  584. down(&parent->sem);
  585. list_del_init(&class_intf->node);
  586. if (class_intf->remove) {
  587. list_for_each_entry(class_dev, &parent->children, node)
  588. class_intf->remove(class_dev);
  589. }
  590. up(&parent->sem);
  591. class_put(parent);
  592. }
  593. int __init classes_init(void)
  594. {
  595. int retval;
  596. retval = subsystem_register(&class_subsys);
  597. if (retval)
  598. return retval;
  599. /* ick, this is ugly, the things we go through to keep from showing up
  600. * in sysfs... */
  601. subsystem_init(&class_obj_subsys);
  602. if (!class_obj_subsys.kset.subsys)
  603. class_obj_subsys.kset.subsys = &class_obj_subsys;
  604. return 0;
  605. }
  606. EXPORT_SYMBOL_GPL(class_create_file);
  607. EXPORT_SYMBOL_GPL(class_remove_file);
  608. EXPORT_SYMBOL_GPL(class_register);
  609. EXPORT_SYMBOL_GPL(class_unregister);
  610. EXPORT_SYMBOL_GPL(class_get);
  611. EXPORT_SYMBOL_GPL(class_put);
  612. EXPORT_SYMBOL_GPL(class_create);
  613. EXPORT_SYMBOL_GPL(class_destroy);
  614. EXPORT_SYMBOL_GPL(class_device_register);
  615. EXPORT_SYMBOL_GPL(class_device_unregister);
  616. EXPORT_SYMBOL_GPL(class_device_initialize);
  617. EXPORT_SYMBOL_GPL(class_device_add);
  618. EXPORT_SYMBOL_GPL(class_device_del);
  619. EXPORT_SYMBOL_GPL(class_device_get);
  620. EXPORT_SYMBOL_GPL(class_device_put);
  621. EXPORT_SYMBOL_GPL(class_device_create);
  622. EXPORT_SYMBOL_GPL(class_device_destroy);
  623. EXPORT_SYMBOL_GPL(class_device_create_file);
  624. EXPORT_SYMBOL_GPL(class_device_remove_file);
  625. EXPORT_SYMBOL_GPL(class_device_create_bin_file);
  626. EXPORT_SYMBOL_GPL(class_device_remove_bin_file);
  627. EXPORT_SYMBOL_GPL(class_interface_register);
  628. EXPORT_SYMBOL_GPL(class_interface_unregister);