tile-srom.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  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 *file, loff_t offset, int origin)
  240. {
  241. struct srom_dev *srom = file->private_data;
  242. return fixed_size_llseek(file, offset, origin, srom->total_size);
  243. }
  244. static ssize_t total_size_show(struct device *dev,
  245. struct device_attribute *attr, char *buf)
  246. {
  247. struct srom_dev *srom = dev_get_drvdata(dev);
  248. return sprintf(buf, "%u\n", srom->total_size);
  249. }
  250. static DEVICE_ATTR_RO(total_size);
  251. static ssize_t sector_size_show(struct device *dev,
  252. struct device_attribute *attr, char *buf)
  253. {
  254. struct srom_dev *srom = dev_get_drvdata(dev);
  255. return sprintf(buf, "%u\n", srom->sector_size);
  256. }
  257. static DEVICE_ATTR_RO(sector_size);
  258. static ssize_t page_size_show(struct device *dev,
  259. struct device_attribute *attr, char *buf)
  260. {
  261. struct srom_dev *srom = dev_get_drvdata(dev);
  262. return sprintf(buf, "%u\n", srom->page_size);
  263. }
  264. static DEVICE_ATTR_RO(page_size);
  265. static struct attribute *srom_dev_attrs[] = {
  266. &dev_attr_total_size.attr,
  267. &dev_attr_sector_size.attr,
  268. &dev_attr_page_size.attr,
  269. NULL,
  270. };
  271. ATTRIBUTE_GROUPS(srom_dev);
  272. static char *srom_devnode(struct device *dev, umode_t *mode)
  273. {
  274. *mode = S_IRUGO | S_IWUSR;
  275. return kasprintf(GFP_KERNEL, "srom/%s", dev_name(dev));
  276. }
  277. /*
  278. * The fops
  279. */
  280. static const struct file_operations srom_fops = {
  281. .owner = THIS_MODULE,
  282. .llseek = srom_llseek,
  283. .read = srom_read,
  284. .write = srom_write,
  285. .open = srom_open,
  286. .release = srom_release,
  287. };
  288. /**
  289. * srom_setup_minor() - Initialize per-minor information.
  290. * @srom: Per-device SROM state.
  291. * @index: Device to set up.
  292. */
  293. static int srom_setup_minor(struct srom_dev *srom, int index)
  294. {
  295. struct device *dev;
  296. int devhdl = srom->hv_devhdl;
  297. mutex_init(&srom->lock);
  298. if (_srom_read(devhdl, &srom->total_size,
  299. SROM_TOTAL_SIZE_OFF, sizeof(srom->total_size)) < 0)
  300. return -EIO;
  301. if (_srom_read(devhdl, &srom->sector_size,
  302. SROM_SECTOR_SIZE_OFF, sizeof(srom->sector_size)) < 0)
  303. return -EIO;
  304. if (_srom_read(devhdl, &srom->page_size,
  305. SROM_PAGE_SIZE_OFF, sizeof(srom->page_size)) < 0)
  306. return -EIO;
  307. dev = device_create(srom_class, &platform_bus,
  308. MKDEV(srom_major, index), srom, "%d", index);
  309. return PTR_ERR_OR_ZERO(dev);
  310. }
  311. /** srom_init() - Initialize the driver's module. */
  312. static int srom_init(void)
  313. {
  314. int result, i;
  315. dev_t dev = MKDEV(srom_major, 0);
  316. /*
  317. * Start with a plausible number of partitions; the krealloc() call
  318. * below will yield about log(srom_devs) additional allocations.
  319. */
  320. srom_devices = kzalloc(4 * sizeof(struct srom_dev), GFP_KERNEL);
  321. /* Discover the number of srom partitions. */
  322. for (i = 0; ; i++) {
  323. int devhdl;
  324. char buf[20];
  325. struct srom_dev *new_srom_devices =
  326. krealloc(srom_devices, (i+1) * sizeof(struct srom_dev),
  327. GFP_KERNEL | __GFP_ZERO);
  328. if (!new_srom_devices) {
  329. result = -ENOMEM;
  330. goto fail_mem;
  331. }
  332. srom_devices = new_srom_devices;
  333. sprintf(buf, "srom/0/%d", i);
  334. devhdl = hv_dev_open((HV_VirtAddr)buf, 0);
  335. if (devhdl < 0) {
  336. if (devhdl != HV_ENODEV)
  337. pr_notice("srom/%d: hv_dev_open failed: %d.\n",
  338. i, devhdl);
  339. break;
  340. }
  341. srom_devices[i].hv_devhdl = devhdl;
  342. }
  343. srom_devs = i;
  344. /* Bail out early if we have no partitions at all. */
  345. if (srom_devs == 0) {
  346. result = -ENODEV;
  347. goto fail_mem;
  348. }
  349. /* Register our major, and accept a dynamic number. */
  350. if (srom_major)
  351. result = register_chrdev_region(dev, srom_devs, "srom");
  352. else {
  353. result = alloc_chrdev_region(&dev, 0, srom_devs, "srom");
  354. srom_major = MAJOR(dev);
  355. }
  356. if (result < 0)
  357. goto fail_mem;
  358. /* Register a character device. */
  359. cdev_init(&srom_cdev, &srom_fops);
  360. srom_cdev.owner = THIS_MODULE;
  361. srom_cdev.ops = &srom_fops;
  362. result = cdev_add(&srom_cdev, dev, srom_devs);
  363. if (result < 0)
  364. goto fail_chrdev;
  365. /* Create a sysfs class. */
  366. srom_class = class_create(THIS_MODULE, "srom");
  367. if (IS_ERR(srom_class)) {
  368. result = PTR_ERR(srom_class);
  369. goto fail_cdev;
  370. }
  371. srom_class->dev_groups = srom_dev_groups;
  372. srom_class->devnode = srom_devnode;
  373. /* Do per-partition initialization */
  374. for (i = 0; i < srom_devs; i++) {
  375. result = srom_setup_minor(srom_devices + i, i);
  376. if (result < 0)
  377. goto fail_class;
  378. }
  379. return 0;
  380. fail_class:
  381. for (i = 0; i < srom_devs; i++)
  382. device_destroy(srom_class, MKDEV(srom_major, i));
  383. class_destroy(srom_class);
  384. fail_cdev:
  385. cdev_del(&srom_cdev);
  386. fail_chrdev:
  387. unregister_chrdev_region(dev, srom_devs);
  388. fail_mem:
  389. kfree(srom_devices);
  390. return result;
  391. }
  392. /** srom_cleanup() - Clean up the driver's module. */
  393. static void srom_cleanup(void)
  394. {
  395. int i;
  396. for (i = 0; i < srom_devs; i++)
  397. device_destroy(srom_class, MKDEV(srom_major, i));
  398. class_destroy(srom_class);
  399. cdev_del(&srom_cdev);
  400. unregister_chrdev_region(MKDEV(srom_major, 0), srom_devs);
  401. kfree(srom_devices);
  402. }
  403. module_init(srom_init);
  404. module_exit(srom_cleanup);