rmi_dev.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. /* Synaptics Register Mapped Interface (RMI4) I2C Physical Layer Driver.
  2. * Copyright (c) 2007-2012, Synaptics Incorporated
  3. *
  4. * This software is licensed under the terms of the GNU General Public
  5. * License version 2, as published by the Free Software Foundation, and
  6. * may be copied, distributed, and modified under those terms.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. */
  14. #include "synaptics_i2c_rmi.h"
  15. #define CHAR_DEVICE_NAME "rmi"
  16. #define DEVICE_CLASS_NAME "rmidev"
  17. #define DEV_NUMBER 1
  18. #define REG_ADDR_LIMIT 0xFFFF
  19. static ssize_t rmidev_sysfs_data_show(struct file *data_file,
  20. struct kobject *kobj, struct bin_attribute *attributes,
  21. char *buf, loff_t pos, size_t count);
  22. static ssize_t rmidev_sysfs_data_store(struct file *data_file,
  23. struct kobject *kobj, struct bin_attribute *attributes,
  24. char *buf, loff_t pos, size_t count);
  25. static ssize_t rmidev_sysfs_open_store(struct device *dev,
  26. struct device_attribute *attr, const char *buf, size_t count);
  27. static ssize_t rmidev_sysfs_release_store(struct device *dev,
  28. struct device_attribute *attr, const char *buf, size_t count);
  29. static ssize_t rmidev_sysfs_address_store(struct device *dev,
  30. struct device_attribute *attr, const char *buf, size_t count);
  31. static ssize_t rmidev_sysfs_length_store(struct device *dev,
  32. struct device_attribute *attr, const char *buf, size_t count);
  33. static ssize_t rmidev_sysfs_attn_state_show(struct device *dev,
  34. struct device_attribute *attr, char *buf);
  35. struct rmidev_handle {
  36. dev_t dev_no;
  37. unsigned short address;
  38. unsigned int length;
  39. struct device dev;
  40. struct synaptics_rmi4_data *rmi4_data;
  41. struct synaptics_rmi4_exp_fn_ptr *fn_ptr;
  42. struct kobject *sysfs_dir;
  43. void *data;
  44. };
  45. struct rmidev_data {
  46. int ref_count;
  47. struct cdev main_dev;
  48. struct class *device_class;
  49. struct mutex file_mutex;
  50. struct rmidev_handle *rmi_dev;
  51. };
  52. static struct bin_attribute attr_data = {
  53. .attr = {
  54. .name = "data",
  55. .mode = (S_IRUGO | S_IWUSR | S_IWGRP),
  56. },
  57. .size = 0,
  58. .read = rmidev_sysfs_data_show,
  59. .write = rmidev_sysfs_data_store,
  60. };
  61. static struct device_attribute attrs[] = {
  62. __ATTR(open, S_IWUSR | S_IWGRP,
  63. synaptics_rmi4_show_error,
  64. rmidev_sysfs_open_store),
  65. __ATTR(release, S_IWUSR | S_IWGRP,
  66. synaptics_rmi4_show_error,
  67. rmidev_sysfs_release_store),
  68. __ATTR(address, S_IWUSR | S_IWGRP,
  69. synaptics_rmi4_show_error,
  70. rmidev_sysfs_address_store),
  71. __ATTR(length, S_IWUSR | S_IWGRP,
  72. synaptics_rmi4_show_error,
  73. rmidev_sysfs_length_store),
  74. __ATTR(attn_state, S_IRUGO,
  75. rmidev_sysfs_attn_state_show,
  76. synaptics_rmi4_store_error),
  77. };
  78. static int rmidev_major_num;
  79. static struct class *rmidev_device_class;
  80. static struct rmidev_handle *rmidev;
  81. static ssize_t rmidev_sysfs_data_show(struct file *data_file,
  82. struct kobject *kobj, struct bin_attribute *attributes,
  83. char *buf, loff_t pos, size_t count)
  84. {
  85. int retval;
  86. unsigned int data_length = rmidev->length;
  87. if (data_length > (REG_ADDR_LIMIT - rmidev->address))
  88. data_length = REG_ADDR_LIMIT - rmidev->address;
  89. if (count < data_length) {
  90. dev_err(&rmidev->rmi4_data->i2c_client->dev,
  91. "%s: Not enough space (%d bytes) in buffer\n",
  92. __func__, count);
  93. return -EINVAL;
  94. }
  95. if (data_length) {
  96. retval = rmidev->fn_ptr->read(rmidev->rmi4_data,
  97. rmidev->address,
  98. (unsigned char *)buf,
  99. data_length);
  100. if (retval < 0) {
  101. dev_err(&rmidev->rmi4_data->i2c_client->dev,
  102. "%s: Failed to read data\n",
  103. __func__);
  104. return retval;
  105. }
  106. } else {
  107. return -EINVAL;
  108. }
  109. return data_length;
  110. }
  111. static ssize_t rmidev_sysfs_data_store(struct file *data_file,
  112. struct kobject *kobj, struct bin_attribute *attributes,
  113. char *buf, loff_t pos, size_t count)
  114. {
  115. int retval;
  116. unsigned int data_length = rmidev->length;
  117. if (data_length > (REG_ADDR_LIMIT - rmidev->address))
  118. data_length = REG_ADDR_LIMIT - rmidev->address;
  119. if (data_length) {
  120. retval = rmidev->fn_ptr->write(rmidev->rmi4_data,
  121. rmidev->address,
  122. (unsigned char *)buf,
  123. data_length);
  124. if (retval < 0) {
  125. dev_err(&rmidev->rmi4_data->i2c_client->dev,
  126. "%s: Failed to write data\n",
  127. __func__);
  128. return retval;
  129. }
  130. } else {
  131. return -EINVAL;
  132. }
  133. return count;
  134. }
  135. static ssize_t rmidev_sysfs_open_store(struct device *dev,
  136. struct device_attribute *attr, const char *buf, size_t count)
  137. {
  138. unsigned int input;
  139. if (sscanf(buf, "%u", &input) != 1)
  140. return -EINVAL;
  141. if (input != 1)
  142. return -EINVAL;
  143. rmidev->fn_ptr->enable(rmidev->rmi4_data, false);
  144. dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
  145. "%s: Attention interrupt disabled\n",
  146. __func__);
  147. return count;
  148. }
  149. static ssize_t rmidev_sysfs_release_store(struct device *dev,
  150. struct device_attribute *attr, const char *buf, size_t count)
  151. {
  152. unsigned int input;
  153. if (sscanf(buf, "%u", &input) != 1)
  154. return -EINVAL;
  155. if (input != 1)
  156. return -EINVAL;
  157. rmidev->fn_ptr->enable(rmidev->rmi4_data, true);
  158. dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
  159. "%s: Attention interrupt enabled\n",
  160. __func__);
  161. return count;
  162. }
  163. static ssize_t rmidev_sysfs_address_store(struct device *dev,
  164. struct device_attribute *attr, const char *buf, size_t count)
  165. {
  166. unsigned int input;
  167. if (sscanf(buf, "%u", &input) != 1)
  168. return -EINVAL;
  169. if (input > REG_ADDR_LIMIT)
  170. return -EINVAL;
  171. rmidev->address = (unsigned short)input;
  172. return count;
  173. }
  174. static ssize_t rmidev_sysfs_length_store(struct device *dev,
  175. struct device_attribute *attr, const char *buf, size_t count)
  176. {
  177. unsigned int input;
  178. if (sscanf(buf, "%u", &input) != 1)
  179. return -EINVAL;
  180. if (input > REG_ADDR_LIMIT)
  181. return -EINVAL;
  182. rmidev->length = input;
  183. return count;
  184. }
  185. static ssize_t rmidev_sysfs_attn_state_show(struct device *dev,
  186. struct device_attribute *attr, char *buf)
  187. {
  188. int attn_state;
  189. attn_state = gpio_get_value(rmidev->rmi4_data->dt_data->tsp_int);
  190. return snprintf(buf, PAGE_SIZE, "%u\n", attn_state);
  191. }
  192. /*
  193. * rmidev_llseek - used to set up register address
  194. *
  195. * @filp: file structure for seek
  196. * @off: offset
  197. * if whence == SEEK_SET,
  198. * high 16 bits: page address
  199. * low 16 bits: register address
  200. * if whence == SEEK_CUR,
  201. * offset from current position
  202. * if whence == SEEK_END,
  203. * offset from end position (0xFFFF)
  204. * @whence: SEEK_SET, SEEK_CUR, or SEEK_END
  205. */
  206. static loff_t rmidev_llseek(struct file *filp, loff_t off, int whence)
  207. {
  208. loff_t newpos;
  209. struct rmidev_data *dev_data = filp->private_data;
  210. if (IS_ERR(dev_data)) {
  211. pr_err("%s: Pointer of char device data is invalid", __func__);
  212. return -EBADF;
  213. }
  214. mutex_lock(&(dev_data->file_mutex));
  215. switch (whence) {
  216. case SEEK_SET:
  217. newpos = off;
  218. break;
  219. case SEEK_CUR:
  220. newpos = filp->f_pos + off;
  221. break;
  222. case SEEK_END:
  223. newpos = REG_ADDR_LIMIT + off;
  224. break;
  225. default:
  226. newpos = -EINVAL;
  227. goto clean_up;
  228. }
  229. if (newpos < 0 || newpos > REG_ADDR_LIMIT) {
  230. dev_err(&rmidev->rmi4_data->i2c_client->dev,
  231. "%s: New position 0x%04x is invalid\n",
  232. __func__, (unsigned int)newpos);
  233. newpos = -EINVAL;
  234. goto clean_up;
  235. }
  236. filp->f_pos = newpos;
  237. clean_up:
  238. mutex_unlock(&(dev_data->file_mutex));
  239. return newpos;
  240. }
  241. /*
  242. * rmidev_read: - use to read data from rmi device
  243. *
  244. * @filp: file structure for read
  245. * @buf: user space buffer pointer
  246. * @count: number of bytes to read
  247. * @f_pos: offset (starting register address)
  248. */
  249. static ssize_t rmidev_read(struct file *filp, char __user *buf,
  250. size_t count, loff_t *f_pos)
  251. {
  252. ssize_t retval;
  253. unsigned char tmpbuf[count + 1];
  254. struct rmidev_data *dev_data = filp->private_data;
  255. if (IS_ERR(dev_data)) {
  256. pr_err("%s: Pointer of char device data is invalid", __func__);
  257. return -EBADF;
  258. }
  259. if (count == 0)
  260. return 0;
  261. if (count > (REG_ADDR_LIMIT - *f_pos))
  262. count = REG_ADDR_LIMIT - *f_pos;
  263. mutex_lock(&(dev_data->file_mutex));
  264. retval = rmidev->fn_ptr->read(rmidev->rmi4_data,
  265. *f_pos,
  266. tmpbuf,
  267. count);
  268. if (retval < 0)
  269. goto clean_up;
  270. if (copy_to_user(buf, tmpbuf, count))
  271. retval = -EFAULT;
  272. else
  273. *f_pos += retval;
  274. clean_up:
  275. mutex_unlock(&(dev_data->file_mutex));
  276. return retval;
  277. }
  278. /*
  279. * rmidev_write: - used to write data to rmi device
  280. *
  281. * @filep: file structure for write
  282. * @buf: user space buffer pointer
  283. * @count: number of bytes to write
  284. * @f_pos: offset (starting register address)
  285. */
  286. static ssize_t rmidev_write(struct file *filp, const char __user *buf,
  287. size_t count, loff_t *f_pos)
  288. {
  289. ssize_t retval;
  290. unsigned char tmpbuf[count + 1];
  291. struct rmidev_data *dev_data = filp->private_data;
  292. if (IS_ERR(dev_data)) {
  293. pr_err("%s: Pointer of char device data is invalid", __func__);
  294. return -EBADF;
  295. }
  296. if (count == 0)
  297. return 0;
  298. if (count > (REG_ADDR_LIMIT - *f_pos))
  299. count = REG_ADDR_LIMIT - *f_pos;
  300. if (copy_from_user(tmpbuf, buf, count))
  301. return -EFAULT;
  302. mutex_lock(&(dev_data->file_mutex));
  303. retval = rmidev->fn_ptr->write(rmidev->rmi4_data,
  304. *f_pos,
  305. tmpbuf,
  306. count);
  307. if (retval >= 0)
  308. *f_pos += retval;
  309. mutex_unlock(&(dev_data->file_mutex));
  310. return retval;
  311. }
  312. /*
  313. * rmidev_open: enable access to rmi device
  314. * @inp: inode struture
  315. * @filp: file structure
  316. */
  317. static int rmidev_open(struct inode *inp, struct file *filp)
  318. {
  319. int retval = 0;
  320. struct rmidev_data *dev_data =
  321. container_of(inp->i_cdev, struct rmidev_data, main_dev);
  322. if (!dev_data)
  323. return -EACCES;
  324. filp->private_data = dev_data;
  325. mutex_lock(&(dev_data->file_mutex));
  326. rmidev->fn_ptr->enable(rmidev->rmi4_data, false);
  327. dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
  328. "%s: Attention interrupt disabled\n",
  329. __func__);
  330. if (dev_data->ref_count < 1)
  331. dev_data->ref_count++;
  332. else
  333. retval = -EACCES;
  334. mutex_unlock(&(dev_data->file_mutex));
  335. return retval;
  336. }
  337. /*
  338. * rmidev_release: - release access to rmi device
  339. * @inp: inode structure
  340. * @filp: file structure
  341. */
  342. static int rmidev_release(struct inode *inp, struct file *filp)
  343. {
  344. struct rmidev_data *dev_data =
  345. container_of(inp->i_cdev, struct rmidev_data, main_dev);
  346. if (!dev_data)
  347. return -EACCES;
  348. mutex_lock(&(dev_data->file_mutex));
  349. dev_data->ref_count--;
  350. if (dev_data->ref_count < 0)
  351. dev_data->ref_count = 0;
  352. rmidev->fn_ptr->enable(rmidev->rmi4_data, true);
  353. dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
  354. "%s: Attention interrupt enabled\n",
  355. __func__);
  356. mutex_unlock(&(dev_data->file_mutex));
  357. return 0;
  358. }
  359. static const struct file_operations rmidev_fops = {
  360. .owner = THIS_MODULE,
  361. .llseek = rmidev_llseek,
  362. .read = rmidev_read,
  363. .write = rmidev_write,
  364. .open = rmidev_open,
  365. .release = rmidev_release,
  366. };
  367. static void rmidev_device_cleanup(struct rmidev_data *dev_data)
  368. {
  369. dev_t devno;
  370. if (dev_data) {
  371. devno = dev_data->main_dev.dev;
  372. if (dev_data->device_class)
  373. device_destroy(dev_data->device_class, devno);
  374. cdev_del(&dev_data->main_dev);
  375. unregister_chrdev_region(devno, 1);
  376. dev_dbg(&rmidev->rmi4_data->i2c_client->dev,
  377. "%s: rmidev device removed\n",
  378. __func__);
  379. }
  380. return;
  381. }
  382. static char *rmi_char_devnode(struct device *dev, mode_t *mode)
  383. {
  384. if (!mode)
  385. return NULL;
  386. *mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
  387. return kasprintf(GFP_KERNEL, "rmi/%s", dev_name(dev));
  388. }
  389. static int rmidev_create_device_class(void)
  390. {
  391. rmidev_device_class = class_create(THIS_MODULE, DEVICE_CLASS_NAME);
  392. if (IS_ERR(rmidev_device_class)) {
  393. pr_err("%s: Failed to create /dev/%s\n",
  394. __func__, CHAR_DEVICE_NAME);
  395. return -ENODEV;
  396. }
  397. rmidev_device_class->devnode = rmi_char_devnode;
  398. return 0;
  399. }
  400. static int rmidev_init_device(struct synaptics_rmi4_data *rmi4_data)
  401. {
  402. int retval;
  403. dev_t dev_no;
  404. unsigned char attr_count;
  405. int attr_count_num;
  406. struct rmidev_data *dev_data;
  407. struct device *device_ptr;
  408. rmidev = kzalloc(sizeof(*rmidev), GFP_KERNEL);
  409. if (!rmidev) {
  410. dev_err(&rmi4_data->i2c_client->dev,
  411. "%s: Failed to alloc mem for rmidev\n",
  412. __func__);
  413. retval = -ENOMEM;
  414. goto err_rmidev;
  415. }
  416. rmidev->fn_ptr = kzalloc(sizeof(*(rmidev->fn_ptr)), GFP_KERNEL);
  417. if (!rmidev) {
  418. dev_err(&rmi4_data->i2c_client->dev,
  419. "%s: Failed to alloc mem for fn_ptr\n",
  420. __func__);
  421. retval = -ENOMEM;
  422. goto err_fn_ptr;
  423. }
  424. rmidev->fn_ptr->read = rmi4_data->i2c_read;
  425. rmidev->fn_ptr->write = rmi4_data->i2c_write;
  426. rmidev->fn_ptr->enable = rmi4_data->irq_enable;
  427. rmidev->rmi4_data = rmi4_data;
  428. retval = rmidev_create_device_class();
  429. if (retval < 0) {
  430. dev_err(&rmi4_data->i2c_client->dev,
  431. "%s: Failed to create device class\n",
  432. __func__);
  433. goto err_device_class;
  434. }
  435. if (rmidev_major_num) {
  436. dev_no = MKDEV(rmidev_major_num, DEV_NUMBER);
  437. retval = register_chrdev_region(dev_no, 1, CHAR_DEVICE_NAME);
  438. } else {
  439. retval = alloc_chrdev_region(&dev_no, 0, 1, CHAR_DEVICE_NAME);
  440. if (retval < 0) {
  441. dev_err(&rmi4_data->i2c_client->dev,
  442. "%s: Failed to allocate char device region\n",
  443. __func__);
  444. goto err_device_region;
  445. }
  446. rmidev_major_num = MAJOR(dev_no);
  447. dev_dbg(&rmi4_data->i2c_client->dev,
  448. "%s: Major number of rmidev = %d\n",
  449. __func__, rmidev_major_num);
  450. }
  451. dev_data = kzalloc(sizeof(*dev_data), GFP_KERNEL);
  452. if (!dev_data) {
  453. dev_err(&rmi4_data->i2c_client->dev,
  454. "%s: Failed to alloc mem for dev_data\n",
  455. __func__);
  456. retval = -ENOMEM;
  457. goto err_dev_data;
  458. }
  459. mutex_init(&dev_data->file_mutex);
  460. dev_data->rmi_dev = rmidev;
  461. rmidev->data = dev_data;
  462. cdev_init(&dev_data->main_dev, &rmidev_fops);
  463. retval = cdev_add(&dev_data->main_dev, dev_no, 1);
  464. if (retval < 0) {
  465. dev_err(&rmi4_data->i2c_client->dev,
  466. "%s: Failed to add rmi char device\n",
  467. __func__);
  468. goto err_char_device;
  469. }
  470. dev_set_name(&rmidev->dev, "rmidev%d", MINOR(dev_no));
  471. dev_data->device_class = rmidev_device_class;
  472. device_ptr = device_create(dev_data->device_class, NULL, dev_no,
  473. NULL, CHAR_DEVICE_NAME"%d", MINOR(dev_no));
  474. if (IS_ERR(device_ptr)) {
  475. dev_err(&rmi4_data->i2c_client->dev,
  476. "%s: Failed to create rmi char device\n",
  477. __func__);
  478. retval = -ENODEV;
  479. goto err_char_device;
  480. }
  481. retval = gpio_export(rmi4_data->dt_data->tsp_int, false);
  482. if (retval < 0) {
  483. dev_err(&rmi4_data->i2c_client->dev,
  484. "%s: Failed to export attention gpio\n",
  485. __func__);
  486. } else {
  487. retval = gpio_export_link(&(rmi4_data->input_dev->dev),
  488. "attn", rmi4_data->dt_data->tsp_int);
  489. if (retval < 0) {
  490. dev_err(&rmi4_data->input_dev->dev,
  491. "%s Failed to create gpio symlink\n",
  492. __func__);
  493. } else {
  494. dev_dbg(&rmi4_data->input_dev->dev,
  495. "%s: Exported attention gpio %d\n",
  496. __func__, rmi4_data->dt_data->tsp_int);
  497. }
  498. }
  499. rmidev->sysfs_dir = kobject_create_and_add("rmidev",
  500. &rmi4_data->input_dev->dev.kobj);
  501. if (!rmidev->sysfs_dir) {
  502. dev_err(&rmi4_data->i2c_client->dev,
  503. "%s: Failed to create sysfs directory\n",
  504. __func__);
  505. goto err_sysfs_dir;
  506. }
  507. retval = sysfs_create_bin_file(rmidev->sysfs_dir,
  508. &attr_data);
  509. if (retval < 0) {
  510. dev_err(&rmi4_data->i2c_client->dev,
  511. "%s: Failed to create sysfs bin file\n",
  512. __func__);
  513. goto err_sysfs_bin;
  514. }
  515. for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++) {
  516. retval = sysfs_create_file(rmidev->sysfs_dir,
  517. &attrs[attr_count].attr);
  518. if (retval < 0) {
  519. dev_err(&rmi4_data->input_dev->dev,
  520. "%s: Failed to create sysfs attributes\n",
  521. __func__);
  522. retval = -ENODEV;
  523. goto err_sysfs_attrs;
  524. }
  525. }
  526. return 0;
  527. err_sysfs_attrs:
  528. attr_count_num = (int)attr_count;
  529. for (attr_count_num--; attr_count_num >= 0; attr_count_num--)
  530. sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr);
  531. sysfs_remove_bin_file(rmidev->sysfs_dir, &attr_data);
  532. err_sysfs_bin:
  533. kobject_put(rmidev->sysfs_dir);
  534. err_sysfs_dir:
  535. err_char_device:
  536. rmidev_device_cleanup(dev_data);
  537. kfree(dev_data);
  538. err_dev_data:
  539. unregister_chrdev_region(dev_no, 1);
  540. err_device_region:
  541. class_destroy(rmidev_device_class);
  542. err_device_class:
  543. kfree(rmidev->fn_ptr);
  544. err_fn_ptr:
  545. kfree(rmidev);
  546. err_rmidev:
  547. return retval;
  548. }
  549. static void rmidev_remove_device(struct synaptics_rmi4_data *rmi4_data)
  550. {
  551. unsigned char attr_count;
  552. struct rmidev_data *dev_data;
  553. if (!rmidev)
  554. return;
  555. for (attr_count = 0; attr_count < ARRAY_SIZE(attrs); attr_count++)
  556. sysfs_remove_file(rmidev->sysfs_dir, &attrs[attr_count].attr);
  557. sysfs_remove_bin_file(rmidev->sysfs_dir, &attr_data);
  558. kobject_put(rmidev->sysfs_dir);
  559. dev_data = rmidev->data;
  560. if (dev_data) {
  561. rmidev_device_cleanup(dev_data);
  562. kfree(dev_data);
  563. }
  564. unregister_chrdev_region(rmidev->dev_no, 1);
  565. class_destroy(rmidev_device_class);
  566. kfree(rmidev->fn_ptr);
  567. kfree(rmidev);
  568. return;
  569. }
  570. int rmidev_module_register(void)
  571. {
  572. int retval;
  573. retval = synaptics_rmi4_new_function(RMI_DEV,
  574. rmidev_init_device,
  575. rmidev_remove_device,
  576. NULL);
  577. return retval;
  578. }