1 /* SPDX-License-Identifier: GPL-2.0 */ 2 #ifndef _LINUX_NVRAM_H 3 #define _LINUX_NVRAM_H 4 5 #include <linux/errno.h> 6 #include <uapi/linux/nvram.h> 7 8 #ifdef CONFIG_PPC 9 #include <asm/machdep.h> 10 #endif 11 12 /** 13 * struct nvram_ops - NVRAM functionality made available to drivers 14 * @read: validate checksum (if any) then load a range of bytes from NVRAM 15 * @write: store a range of bytes to NVRAM then update checksum (if any) 16 * @read_byte: load a single byte from NVRAM 17 * @write_byte: store a single byte to NVRAM 18 * @get_size: return the fixed number of bytes in the NVRAM 19 * 20 * Architectures which provide an nvram ops struct need not implement all 21 * of these methods. If the NVRAM hardware can be accessed only one byte 22 * at a time then it may be sufficient to provide .read_byte and .write_byte. 23 * If the NVRAM has a checksum (and it is to be checked) the .read and 24 * .write methods can be used to implement that efficiently. 25 * 26 * Portable drivers may use the wrapper functions defined here. 27 * The nvram_read() and nvram_write() functions call the .read and .write 28 * methods when available and fall back on the .read_byte and .write_byte 29 * methods otherwise. 30 */ 31 32 struct nvram_ops { 33 ssize_t (*get_size)(void); 34 unsigned char (*read_byte)(int); 35 void (*write_byte)(unsigned char, int); 36 ssize_t (*read)(char *, size_t, loff_t *); 37 ssize_t (*write)(char *, size_t, loff_t *); 38 #if defined(CONFIG_X86) || defined(CONFIG_M68K) 39 long (*initialize)(void); 40 long (*set_checksum)(void); 41 #endif 42 }; 43 44 extern const struct nvram_ops arch_nvram_ops; 45 46 static inline ssize_t nvram_get_size(void) 47 { 48 #ifdef CONFIG_PPC 49 if (ppc_md.nvram_size) 50 return ppc_md.nvram_size(); 51 #else 52 if (arch_nvram_ops.get_size) 53 return arch_nvram_ops.get_size(); 54 #endif 55 return -ENODEV; 56 } 57 58 static inline unsigned char nvram_read_byte(int addr) 59 { 60 #ifdef CONFIG_PPC 61 if (ppc_md.nvram_read_val) 62 return ppc_md.nvram_read_val(addr); 63 #else 64 if (arch_nvram_ops.read_byte) 65 return arch_nvram_ops.read_byte(addr); 66 #endif 67 return 0xFF; 68 } 69 70 static inline void nvram_write_byte(unsigned char val, int addr) 71 { 72 #ifdef CONFIG_PPC 73 if (ppc_md.nvram_write_val) 74 ppc_md.nvram_write_val(addr, val); 75 #else 76 if (arch_nvram_ops.write_byte) 77 arch_nvram_ops.write_byte(val, addr); 78 #endif 79 } 80 81 static inline ssize_t nvram_read_bytes(char *buf, size_t count, loff_t *ppos) 82 { 83 ssize_t nvram_size = nvram_get_size(); 84 loff_t i; 85 char *p = buf; 86 87 if (nvram_size < 0) 88 return nvram_size; 89 for (i = *ppos; count > 0 && i < nvram_size; ++i, ++p, --count) 90 *p = nvram_read_byte(i); 91 *ppos = i; 92 return p - buf; 93 } 94 95 static inline ssize_t nvram_write_bytes(char *buf, size_t count, loff_t *ppos) 96 { 97 ssize_t nvram_size = nvram_get_size(); 98 loff_t i; 99 char *p = buf; 100 101 if (nvram_size < 0) 102 return nvram_size; 103 for (i = *ppos; count > 0 && i < nvram_size; ++i, ++p, --count) 104 nvram_write_byte(*p, i); 105 *ppos = i; 106 return p - buf; 107 } 108 109 static inline ssize_t nvram_read(char *buf, size_t count, loff_t *ppos) 110 { 111 #ifdef CONFIG_PPC 112 if (ppc_md.nvram_read) 113 return ppc_md.nvram_read(buf, count, ppos); 114 #else 115 if (arch_nvram_ops.read) 116 return arch_nvram_ops.read(buf, count, ppos); 117 #endif 118 return nvram_read_bytes(buf, count, ppos); 119 } 120 121 static inline ssize_t nvram_write(char *buf, size_t count, loff_t *ppos) 122 { 123 #ifdef CONFIG_PPC 124 if (ppc_md.nvram_write) 125 return ppc_md.nvram_write(buf, count, ppos); 126 #else 127 if (arch_nvram_ops.write) 128 return arch_nvram_ops.write(buf, count, ppos); 129 #endif 130 return nvram_write_bytes(buf, count, ppos); 131 } 132 133 #endif /* _LINUX_NVRAM_H */ 134
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.