bfin-otp.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * Blackfin On-Chip OTP Memory Interface
  3. *
  4. * Copyright 2007-2009 Analog Devices Inc.
  5. *
  6. * Enter bugs at http://blackfin.uclinux.org/
  7. *
  8. * Licensed under the GPL-2 or later.
  9. */
  10. #include <linux/device.h>
  11. #include <linux/errno.h>
  12. #include <linux/fs.h>
  13. #include <linux/init.h>
  14. #include <linux/miscdevice.h>
  15. #include <linux/module.h>
  16. #include <linux/mutex.h>
  17. #include <linux/types.h>
  18. #include <mtd/mtd-abi.h>
  19. #include <asm/blackfin.h>
  20. #include <asm/bfrom.h>
  21. #include <asm/uaccess.h>
  22. #define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __func__, __LINE__, ## args)
  23. #define stampit() stamp("here i am")
  24. #define pr_init(fmt, args...) ({ static const __initconst char __fmt[] = fmt; printk(__fmt, ## args); })
  25. #define DRIVER_NAME "bfin-otp"
  26. #define PFX DRIVER_NAME ": "
  27. static DEFINE_MUTEX(bfin_otp_lock);
  28. /**
  29. * bfin_otp_read - Read OTP pages
  30. *
  31. * All reads must be in half page chunks (half page == 64 bits).
  32. */
  33. static ssize_t bfin_otp_read(struct file *file, char __user *buff, size_t count, loff_t *pos)
  34. {
  35. ssize_t bytes_done;
  36. u32 page, flags, ret;
  37. u64 content;
  38. stampit();
  39. if (count % sizeof(u64))
  40. return -EMSGSIZE;
  41. if (mutex_lock_interruptible(&bfin_otp_lock))
  42. return -ERESTARTSYS;
  43. bytes_done = 0;
  44. page = *pos / (sizeof(u64) * 2);
  45. while (bytes_done < count) {
  46. flags = (*pos % (sizeof(u64) * 2) ? OTP_UPPER_HALF : OTP_LOWER_HALF);
  47. stamp("processing page %i (0x%x:%s)", page, flags,
  48. (flags & OTP_UPPER_HALF ? "upper" : "lower"));
  49. ret = bfrom_OtpRead(page, flags, &content);
  50. if (ret & OTP_MASTER_ERROR) {
  51. stamp("error from otp: 0x%x", ret);
  52. bytes_done = -EIO;
  53. break;
  54. }
  55. if (copy_to_user(buff + bytes_done, &content, sizeof(content))) {
  56. bytes_done = -EFAULT;
  57. break;
  58. }
  59. if (flags & OTP_UPPER_HALF)
  60. ++page;
  61. bytes_done += sizeof(content);
  62. *pos += sizeof(content);
  63. }
  64. mutex_unlock(&bfin_otp_lock);
  65. return bytes_done;
  66. }
  67. #ifdef CONFIG_BFIN_OTP_WRITE_ENABLE
  68. static bool allow_writes;
  69. /**
  70. * bfin_otp_init_timing - setup OTP timing parameters
  71. *
  72. * Required before doing any write operation. Algorithms from HRM.
  73. */
  74. static u32 bfin_otp_init_timing(void)
  75. {
  76. u32 tp1, tp2, tp3, timing;
  77. tp1 = get_sclk() / 1000000;
  78. tp2 = (2 * get_sclk() / 10000000) << 8;
  79. tp3 = (0x1401) << 15;
  80. timing = tp1 | tp2 | tp3;
  81. if (bfrom_OtpCommand(OTP_INIT, timing))
  82. return 0;
  83. return timing;
  84. }
  85. /**
  86. * bfin_otp_deinit_timing - set timings to only allow reads
  87. *
  88. * Should be called after all writes are done.
  89. */
  90. static void bfin_otp_deinit_timing(u32 timing)
  91. {
  92. /* mask bits [31:15] so that any attempts to write fail */
  93. bfrom_OtpCommand(OTP_CLOSE, 0);
  94. bfrom_OtpCommand(OTP_INIT, timing & ~(-1 << 15));
  95. bfrom_OtpCommand(OTP_CLOSE, 0);
  96. }
  97. /**
  98. * bfin_otp_write - write OTP pages
  99. *
  100. * All writes must be in half page chunks (half page == 64 bits).
  101. */
  102. static ssize_t bfin_otp_write(struct file *filp, const char __user *buff, size_t count, loff_t *pos)
  103. {
  104. ssize_t bytes_done;
  105. u32 timing, page, base_flags, flags, ret;
  106. u64 content;
  107. if (!allow_writes)
  108. return -EACCES;
  109. if (count % sizeof(u64))
  110. return -EMSGSIZE;
  111. if (mutex_lock_interruptible(&bfin_otp_lock))
  112. return -ERESTARTSYS;
  113. stampit();
  114. timing = bfin_otp_init_timing();
  115. if (timing == 0) {
  116. mutex_unlock(&bfin_otp_lock);
  117. return -EIO;
  118. }
  119. base_flags = OTP_CHECK_FOR_PREV_WRITE;
  120. bytes_done = 0;
  121. page = *pos / (sizeof(u64) * 2);
  122. while (bytes_done < count) {
  123. flags = base_flags | (*pos % (sizeof(u64) * 2) ? OTP_UPPER_HALF : OTP_LOWER_HALF);
  124. stamp("processing page %i (0x%x:%s) from %p", page, flags,
  125. (flags & OTP_UPPER_HALF ? "upper" : "lower"), buff + bytes_done);
  126. if (copy_from_user(&content, buff + bytes_done, sizeof(content))) {
  127. bytes_done = -EFAULT;
  128. break;
  129. }
  130. ret = bfrom_OtpWrite(page, flags, &content);
  131. if (ret & OTP_MASTER_ERROR) {
  132. stamp("error from otp: 0x%x", ret);
  133. bytes_done = -EIO;
  134. break;
  135. }
  136. if (flags & OTP_UPPER_HALF)
  137. ++page;
  138. bytes_done += sizeof(content);
  139. *pos += sizeof(content);
  140. }
  141. bfin_otp_deinit_timing(timing);
  142. mutex_unlock(&bfin_otp_lock);
  143. return bytes_done;
  144. }
  145. static long bfin_otp_ioctl(struct file *filp, unsigned cmd, unsigned long arg)
  146. {
  147. stampit();
  148. switch (cmd) {
  149. case OTPLOCK: {
  150. u32 timing;
  151. int ret = -EIO;
  152. if (!allow_writes)
  153. return -EACCES;
  154. if (mutex_lock_interruptible(&bfin_otp_lock))
  155. return -ERESTARTSYS;
  156. timing = bfin_otp_init_timing();
  157. if (timing) {
  158. u32 otp_result = bfrom_OtpWrite(arg, OTP_LOCK, NULL);
  159. stamp("locking page %lu resulted in 0x%x", arg, otp_result);
  160. if (!(otp_result & OTP_MASTER_ERROR))
  161. ret = 0;
  162. bfin_otp_deinit_timing(timing);
  163. }
  164. mutex_unlock(&bfin_otp_lock);
  165. return ret;
  166. }
  167. case MEMLOCK:
  168. allow_writes = false;
  169. return 0;
  170. case MEMUNLOCK:
  171. allow_writes = true;
  172. return 0;
  173. }
  174. return -EINVAL;
  175. }
  176. #else
  177. # define bfin_otp_write NULL
  178. # define bfin_otp_ioctl NULL
  179. #endif
  180. static const struct file_operations bfin_otp_fops = {
  181. .owner = THIS_MODULE,
  182. .unlocked_ioctl = bfin_otp_ioctl,
  183. .read = bfin_otp_read,
  184. .write = bfin_otp_write,
  185. .llseek = default_llseek,
  186. };
  187. static struct miscdevice bfin_otp_misc_device = {
  188. .minor = MISC_DYNAMIC_MINOR,
  189. .name = DRIVER_NAME,
  190. .fops = &bfin_otp_fops,
  191. };
  192. /**
  193. * bfin_otp_init - Initialize module
  194. *
  195. * Registers the device and notifier handler. Actual device
  196. * initialization is handled by bfin_otp_open().
  197. */
  198. static int __init bfin_otp_init(void)
  199. {
  200. int ret;
  201. stampit();
  202. ret = misc_register(&bfin_otp_misc_device);
  203. if (ret) {
  204. pr_init(KERN_ERR PFX "unable to register a misc device\n");
  205. return ret;
  206. }
  207. pr_init(KERN_INFO PFX "initialized\n");
  208. return 0;
  209. }
  210. /**
  211. * bfin_otp_exit - Deinitialize module
  212. *
  213. * Unregisters the device and notifier handler. Actual device
  214. * deinitialization is handled by bfin_otp_close().
  215. */
  216. static void __exit bfin_otp_exit(void)
  217. {
  218. stampit();
  219. misc_deregister(&bfin_otp_misc_device);
  220. }
  221. module_init(bfin_otp_init);
  222. module_exit(bfin_otp_exit);
  223. MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
  224. MODULE_DESCRIPTION("Blackfin OTP Memory Interface");
  225. MODULE_LICENSE("GPL");