tile-srom.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. /*
  2. * Copyright 2011 Tilera Corporation. All Rights Reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation, version 2.
  7. *
  8. * This program is distributed in the hope that it will be useful, but
  9. * WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  11. * NON INFRINGEMENT. See the GNU General Public License for
  12. * more details.
  13. *
  14. * SPI Flash ROM driver
  15. *
  16. * This source code is derived from code provided in "Linux Device
  17. * Drivers, Third Edition", by Jonathan Corbet, Alessandro Rubini, and
  18. * Greg Kroah-Hartman, published by O'Reilly Media, Inc.
  19. */
  20. #include <linux/module.h>
  21. #include <linux/moduleparam.h>
  22. #include <linux/init.h>
  23. #include <linux/kernel.h> /* printk() */
  24. #include <linux/slab.h> /* kmalloc() */
  25. #include <linux/fs.h> /* everything... */
  26. #include <linux/errno.h> /* error codes */
  27. #include <linux/types.h> /* size_t */
  28. #include <linux/proc_fs.h>
  29. #include <linux/fcntl.h> /* O_ACCMODE */
  30. #include <linux/aio.h>
  31. #include <linux/pagemap.h>
  32. #include <linux/hugetlb.h>
  33. #include <linux/uaccess.h>
  34. #include <linux/platform_device.h>
  35. #include <hv/hypervisor.h>
  36. #include <linux/ioctl.h>
  37. #include <linux/cdev.h>
  38. #include <linux/delay.h>
  39. #include <hv/drv_srom_intf.h>
  40. /*
  41. * Size of our hypervisor I/O requests. We break up large transfers
  42. * so that we don't spend large uninterrupted spans of time in the
  43. * hypervisor. Erasing an SROM sector takes a significant fraction of
  44. * a second, so if we allowed the user to, say, do one I/O to write the
  45. * entire ROM, we'd get soft lockup timeouts, or worse.
  46. */
  47. #define SROM_CHUNK_SIZE ((size_t)4096)
  48. /*
  49. * When hypervisor is busy (e.g. erasing), poll the status periodically.
  50. */
  51. /*
  52. * Interval to poll the state in msec
  53. */
  54. #define SROM_WAIT_TRY_INTERVAL 20
  55. /*
  56. * Maximum times to poll the state
  57. */
  58. #define SROM_MAX_WAIT_TRY_TIMES 1000
  59. struct srom_dev {
  60. int hv_devhdl; /* Handle for hypervisor device */
  61. u32 total_size; /* Size of this device */
  62. u32 sector_size; /* Size of a sector */
  63. u32 page_size; /* Size of a page */
  64. struct mutex lock; /* Allow only one accessor at a time */
  65. };
  66. static int srom_major; /* Dynamic major by default */
  67. module_param(srom_major, int, 0);
  68. MODULE_AUTHOR("Tilera Corporation");
  69. MODULE_LICENSE("GPL");
  70. static int srom_devs; /* Number of SROM partitions */
  71. static struct cdev srom_cdev;
  72. static struct class *srom_class;
  73. static struct srom_dev *srom_devices;
  74. /*
  75. * Handle calling the hypervisor and managing EAGAIN/EBUSY.
  76. */
  77. static ssize_t _srom_read(int hv_devhdl, void *buf,
  78. loff_t off, size_t count)
  79. {
  80. int retval, retries = SROM_MAX_WAIT_TRY_TIMES;
  81. for (;;) {
  82. retval = hv_dev_pread(hv_devhdl, 0, (HV_VirtAddr)buf,
  83. count, off);
  84. if (retval >= 0)
  85. return retval;
  86. if (retval == HV_EAGAIN)
  87. continue;
  88. if (retval == HV_EBUSY && --retries > 0) {
  89. msleep(SROM_WAIT_TRY_INTERVAL);
  90. continue;
  91. }
  92. pr_err("_srom_read: error %d\n", retval);
  93. return -EIO;
  94. }
  95. }
  96. static ssize_t _srom_write(int hv_devhdl, const void *buf,
  97. loff_t off, size_t count)
  98. {
  99. int retval, retries = SROM_MAX_WAIT_TRY_TIMES;
  100. for (;;) {
  101. retval = hv_dev_pwrite(hv_devhdl, 0, (HV_VirtAddr)buf,
  102. count, off);
  103. if (retval >= 0)
  104. return retval;
  105. if (retval == HV_EAGAIN)
  106. continue;
  107. if (retval == HV_EBUSY && --retries > 0) {
  108. msleep(SROM_WAIT_TRY_INTERVAL);
  109. continue;
  110. }
  111. pr_err("_srom_write: error %d\n", retval);
  112. return -EIO;
  113. }
  114. }
  115. /**
  116. * srom_open() - Device open routine.
  117. * @inode: Inode for this device.
  118. * @filp: File for this specific open of the device.
  119. *
  120. * Returns zero, or an error code.
  121. */
  122. static int srom_open(struct inode *inode, struct file *filp)
  123. {
  124. filp->private_data = &srom_devices[iminor(inode)];
  125. return 0;
  126. }
  127. /**
  128. * srom_release() - Device release routine.
  129. * @inode: Inode for this device.
  130. * @filp: File for this specific open of the device.
  131. *
  132. * Returns zero, or an error code.
  133. */
  134. static int srom_release(struct inode *inode, struct file *filp)
  135. {
  136. struct srom_dev *srom = filp->private_data;
  137. char dummy;
  138. /* Make sure we've flushed anything written to the ROM. */
  139. mutex_lock(&srom->lock);
  140. if (srom->hv_devhdl >= 0)
  141. _srom_write(srom->hv_devhdl, &dummy, SROM_FLUSH_OFF, 1);
  142. mutex_unlock(&srom->lock);
  143. filp->private_data = NULL;
  144. return 0;
  145. }
  146. /**
  147. * srom_read() - Read data from the device.
  148. * @filp: File for this specific open of the device.
  149. * @buf: User's data buffer.
  150. * @count: Number of bytes requested.
  151. * @f_pos: File position.
  152. *
  153. * Returns number of bytes read, or an error code.
  154. */
  155. static ssize_t srom_read(struct file *filp, char __user *buf,
  156. size_t count, loff_t *f_pos)
  157. {
  158. int retval = 0;
  159. void *kernbuf;
  160. struct srom_dev *srom = filp->private_data;
  161. kernbuf = kmalloc(SROM_CHUNK_SIZE, GFP_KERNEL);
  162. if (!kernbuf)
  163. return -ENOMEM;
  164. if (mutex_lock_interruptible(&srom->lock)) {
  165. retval = -ERESTARTSYS;
  166. kfree(kernbuf);
  167. return retval;
  168. }
  169. while (count) {
  170. int hv_retval;
  171. int bytes_this_pass = min(count, SROM_CHUNK_SIZE);
  172. hv_retval = _srom_read(srom->hv_devhdl, kernbuf,
  173. *f_pos, bytes_this_pass);
  174. if (hv_retval <= 0) {
  175. if (retval == 0)
  176. retval = hv_retval;
  177. break;
  178. }
  179. if (copy_to_user(buf, kernbuf, hv_retval) != 0) {
  180. retval = -EFAULT;
  181. break;
  182. }
  183. retval += hv_retval;
  184. *f_pos += hv_retval;
  185. buf += hv_retval;
  186. count -= hv_retval;
  187. }
  188. mutex_unlock(&srom->lock);
  189. kfree(kernbuf);
  190. return retval;
  191. }
  192. /**
  193. * srom_write() - Write data to the device.
  194. * @filp: File for this specific open of the device.
  195. * @buf: User's data buffer.
  196. * @count: Number of bytes requested.
  197. * @f_pos: File position.
  198. *
  199. * Returns number of bytes written, or an error code.
  200. */
  201. static ssize_t srom_write(struct file *filp, const char __user *buf,
  202. size_t count, loff_t *f_pos)
  203. {
  204. int retval = 0;
  205. void *kernbuf;
  206. struct srom_dev *srom = filp->private_data;
  207. kernbuf = kmalloc(SROM_CHUNK_SIZE, GFP_KERNEL);
  208. if (!kernbuf)
  209. return -ENOMEM;
  210. if (mutex_lock_interruptible(&srom->lock)) {
  211. retval = -ERESTARTSYS;
  212. kfree(kernbuf);
  213. return retval;
  214. }
  215. while (count) {
  216. int hv_retval;
  217. int bytes_this_pass = min(count, SROM_CHUNK_SIZE);
  218. if (copy_from_user(kernbuf, buf, bytes_this_pass) != 0) {
  219. retval = -EFAULT;
  220. break;
  221. }
  222. hv_retval = _srom_write(srom->hv_devhdl, kernbuf,
  223. *f_pos, bytes_this_pass);
  224. if (hv_retval <= 0) {
  225. if (retval == 0)
  226. retval = hv_retval;
  227. break;
  228. }
  229. retval += hv_retval;
  230. *f_pos += hv_retval;
  231. buf += hv_retval;
  232. count -= hv_retval;
  233. }
  234. mutex_unlock(&srom->lock);
  235. kfree(kernbuf);
  236. return retval;
  237. }
  238. /* Provide our own implementation so we can use srom->total_size. */
  239. loff_t srom_llseek(struct file *filp, loff_t offset, int origin)
  240. {
  241. struct srom_dev *srom = filp->private_data;
  242. if (mutex_lock_interruptible(&srom->lock))
  243. return -ERESTARTSYS;
  244. switch (origin) {
  245. case SEEK_END:
  246. offset += srom->total_size;
  247. break;
  248. case SEEK_CUR:
  249. offset += filp->f_pos;
  250. break;
  251. }
  252. if (offset < 0 || offset > srom->total_size) {
  253. offset = -EINVAL;
  254. } else {
  255. filp->f_pos = offset;
  256. filp->f_version = 0;
  257. }
  258. mutex_unlock(&srom->lock);
  259. return offset;
  260. }
  261. static ssize_t total_show(struct device *dev,
  262. struct device_attribute *attr, char *buf)
  263. {
  264. struct srom_dev *srom = dev_get_drvdata(dev);
  265. return sprintf(buf, "%u\n", srom->total_size);
  266. }
  267. static ssize_t sector_show(struct device *dev,
  268. struct device_attribute *attr, char *buf)
  269. {
  270. struct srom_dev *srom = dev_get_drvdata(dev);
  271. return sprintf(buf, "%u\n", srom->sector_size);
  272. }
  273. static ssize_t page_show(struct device *dev,
  274. struct device_attribute *attr, char *buf)
  275. {
  276. struct srom_dev *srom = dev_get_drvdata(dev);
  277. return sprintf(buf, "%u\n", srom->page_size);
  278. }
  279. static struct device_attribute srom_dev_attrs[] = {
  280. __ATTR(total_size, S_IRUGO, total_show, NULL),
  281. __ATTR(sector_size, S_IRUGO, sector_show, NULL),
  282. __ATTR(page_size, S_IRUGO, page_show, NULL),
  283. __ATTR_NULL
  284. };
  285. static char *srom_devnode(struct device *dev, umode_t *mode)
  286. {
  287. *mode = S_IRUGO | S_IWUSR;
  288. return kasprintf(GFP_KERNEL, "srom/%s", dev_name(dev));
  289. }
  290. /*
  291. * The fops
  292. */
  293. static const struct file_operations srom_fops = {
  294. .owner = THIS_MODULE,
  295. .llseek = srom_llseek,
  296. .read = srom_read,
  297. .write = srom_write,
  298. .open = srom_open,
  299. .release = srom_release,
  300. };
  301. /**
  302. * srom_setup_minor() - Initialize per-minor information.
  303. * @srom: Per-device SROM state.
  304. * @index: Device to set up.
  305. */
  306. static int srom_setup_minor(struct srom_dev *srom, int index)
  307. {
  308. struct device *dev;
  309. int devhdl = srom->hv_devhdl;
  310. mutex_init(&srom->lock);
  311. if (_srom_read(devhdl, &srom->total_size,
  312. SROM_TOTAL_SIZE_OFF, sizeof(srom->total_size)) < 0)
  313. return -EIO;
  314. if (_srom_read(devhdl, &srom->sector_size,
  315. SROM_SECTOR_SIZE_OFF, sizeof(srom->sector_size)) < 0)
  316. return -EIO;
  317. if (_srom_read(devhdl, &srom->page_size,
  318. SROM_PAGE_SIZE_OFF, sizeof(srom->page_size)) < 0)
  319. return -EIO;
  320. dev = device_create(srom_class, &platform_bus,
  321. MKDEV(srom_major, index), srom, "%d", index);
  322. return IS_ERR(dev) ? PTR_ERR(dev) : 0;
  323. }
  324. /** srom_init() - Initialize the driver's module. */
  325. static int srom_init(void)
  326. {
  327. int result, i;
  328. dev_t dev = MKDEV(srom_major, 0);
  329. /*
  330. * Start with a plausible number of partitions; the krealloc() call
  331. * below will yield about log(srom_devs) additional allocations.
  332. */
  333. srom_devices = kzalloc(4 * sizeof(struct srom_dev), GFP_KERNEL);
  334. /* Discover the number of srom partitions. */
  335. for (i = 0; ; i++) {
  336. int devhdl;
  337. char buf[20];
  338. struct srom_dev *new_srom_devices =
  339. krealloc(srom_devices, (i+1) * sizeof(struct srom_dev),
  340. GFP_KERNEL | __GFP_ZERO);
  341. if (!new_srom_devices) {
  342. result = -ENOMEM;
  343. goto fail_mem;
  344. }
  345. srom_devices = new_srom_devices;
  346. sprintf(buf, "srom/0/%d", i);
  347. devhdl = hv_dev_open((HV_VirtAddr)buf, 0);
  348. if (devhdl < 0) {
  349. if (devhdl != HV_ENODEV)
  350. pr_notice("srom/%d: hv_dev_open failed: %d.\n",
  351. i, devhdl);
  352. break;
  353. }
  354. srom_devices[i].hv_devhdl = devhdl;
  355. }
  356. srom_devs = i;
  357. /* Bail out early if we have no partitions at all. */
  358. if (srom_devs == 0) {
  359. result = -ENODEV;
  360. goto fail_mem;
  361. }
  362. /* Register our major, and accept a dynamic number. */
  363. if (srom_major)
  364. result = register_chrdev_region(dev, srom_devs, "srom");
  365. else {
  366. result = alloc_chrdev_region(&dev, 0, srom_devs, "srom");
  367. srom_major = MAJOR(dev);
  368. }
  369. if (result < 0)
  370. goto fail_mem;
  371. /* Register a character device. */
  372. cdev_init(&srom_cdev, &srom_fops);
  373. srom_cdev.owner = THIS_MODULE;
  374. srom_cdev.ops = &srom_fops;
  375. result = cdev_add(&srom_cdev, dev, srom_devs);
  376. if (result < 0)
  377. goto fail_chrdev;
  378. /* Create a sysfs class. */
  379. srom_class = class_create(THIS_MODULE, "srom");
  380. if (IS_ERR(srom_class)) {
  381. result = PTR_ERR(srom_class);
  382. goto fail_cdev;
  383. }
  384. srom_class->dev_attrs = srom_dev_attrs;
  385. srom_class->devnode = srom_devnode;
  386. /* Do per-partition initialization */
  387. for (i = 0; i < srom_devs; i++) {
  388. result = srom_setup_minor(srom_devices + i, i);
  389. if (result < 0)
  390. goto fail_class;
  391. }
  392. return 0;
  393. fail_class:
  394. for (i = 0; i < srom_devs; i++)
  395. device_destroy(srom_class, MKDEV(srom_major, i));
  396. class_destroy(srom_class);
  397. fail_cdev:
  398. cdev_del(&srom_cdev);
  399. fail_chrdev:
  400. unregister_chrdev_region(dev, srom_devs);
  401. fail_mem:
  402. kfree(srom_devices);
  403. return result;
  404. }
  405. /** srom_cleanup() - Clean up the driver's module. */
  406. static void srom_cleanup(void)
  407. {
  408. int i;
  409. for (i = 0; i < srom_devs; i++)
  410. device_destroy(srom_class, MKDEV(srom_major, i));
  411. class_destroy(srom_class);
  412. cdev_del(&srom_cdev);
  413. unregister_chrdev_region(MKDEV(srom_major, 0), srom_devs);
  414. kfree(srom_devices);
  415. }
  416. module_init(srom_init);
  417. module_exit(srom_cleanup);