mmio_nvram.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * memory mapped NVRAM
  4. *
  5. * (C) Copyright IBM Corp. 2005
  6. *
  7. * Authors : Utz Bacher <[email protected]>
  8. */
  9. #include <linux/fs.h>
  10. #include <linux/init.h>
  11. #include <linux/kernel.h>
  12. #include <linux/of_address.h>
  13. #include <linux/spinlock.h>
  14. #include <linux/types.h>
  15. #include <asm/machdep.h>
  16. #include <asm/nvram.h>
  17. static void __iomem *mmio_nvram_start;
  18. static long mmio_nvram_len;
  19. static DEFINE_SPINLOCK(mmio_nvram_lock);
  20. static ssize_t mmio_nvram_read(char *buf, size_t count, loff_t *index)
  21. {
  22. unsigned long flags;
  23. if (*index >= mmio_nvram_len)
  24. return 0;
  25. if (*index + count > mmio_nvram_len)
  26. count = mmio_nvram_len - *index;
  27. spin_lock_irqsave(&mmio_nvram_lock, flags);
  28. memcpy_fromio(buf, mmio_nvram_start + *index, count);
  29. spin_unlock_irqrestore(&mmio_nvram_lock, flags);
  30. *index += count;
  31. return count;
  32. }
  33. static unsigned char mmio_nvram_read_val(int addr)
  34. {
  35. unsigned long flags;
  36. unsigned char val;
  37. if (addr >= mmio_nvram_len)
  38. return 0xff;
  39. spin_lock_irqsave(&mmio_nvram_lock, flags);
  40. val = ioread8(mmio_nvram_start + addr);
  41. spin_unlock_irqrestore(&mmio_nvram_lock, flags);
  42. return val;
  43. }
  44. static ssize_t mmio_nvram_write(char *buf, size_t count, loff_t *index)
  45. {
  46. unsigned long flags;
  47. if (*index >= mmio_nvram_len)
  48. return 0;
  49. if (*index + count > mmio_nvram_len)
  50. count = mmio_nvram_len - *index;
  51. spin_lock_irqsave(&mmio_nvram_lock, flags);
  52. memcpy_toio(mmio_nvram_start + *index, buf, count);
  53. spin_unlock_irqrestore(&mmio_nvram_lock, flags);
  54. *index += count;
  55. return count;
  56. }
  57. static void mmio_nvram_write_val(int addr, unsigned char val)
  58. {
  59. unsigned long flags;
  60. if (addr < mmio_nvram_len) {
  61. spin_lock_irqsave(&mmio_nvram_lock, flags);
  62. iowrite8(val, mmio_nvram_start + addr);
  63. spin_unlock_irqrestore(&mmio_nvram_lock, flags);
  64. }
  65. }
  66. static ssize_t mmio_nvram_get_size(void)
  67. {
  68. return mmio_nvram_len;
  69. }
  70. int __init mmio_nvram_init(void)
  71. {
  72. struct device_node *nvram_node;
  73. unsigned long nvram_addr;
  74. struct resource r;
  75. int ret;
  76. nvram_node = of_find_node_by_type(NULL, "nvram");
  77. if (!nvram_node)
  78. nvram_node = of_find_compatible_node(NULL, NULL, "nvram");
  79. if (!nvram_node) {
  80. printk(KERN_WARNING "nvram: no node found in device-tree\n");
  81. return -ENODEV;
  82. }
  83. ret = of_address_to_resource(nvram_node, 0, &r);
  84. if (ret) {
  85. printk(KERN_WARNING "nvram: failed to get address (err %d)\n",
  86. ret);
  87. goto out;
  88. }
  89. nvram_addr = r.start;
  90. mmio_nvram_len = resource_size(&r);
  91. if ( (!mmio_nvram_len) || (!nvram_addr) ) {
  92. printk(KERN_WARNING "nvram: address or length is 0\n");
  93. ret = -EIO;
  94. goto out;
  95. }
  96. mmio_nvram_start = ioremap(nvram_addr, mmio_nvram_len);
  97. if (!mmio_nvram_start) {
  98. printk(KERN_WARNING "nvram: failed to ioremap\n");
  99. ret = -ENOMEM;
  100. goto out;
  101. }
  102. printk(KERN_INFO "mmio NVRAM, %luk at 0x%lx mapped to %p\n",
  103. mmio_nvram_len >> 10, nvram_addr, mmio_nvram_start);
  104. ppc_md.nvram_read_val = mmio_nvram_read_val;
  105. ppc_md.nvram_write_val = mmio_nvram_write_val;
  106. ppc_md.nvram_read = mmio_nvram_read;
  107. ppc_md.nvram_write = mmio_nvram_write;
  108. ppc_md.nvram_size = mmio_nvram_get_size;
  109. out:
  110. of_node_put(nvram_node);
  111. return ret;
  112. }