nvram.h (3550B)
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 32struct 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 44extern const struct nvram_ops arch_nvram_ops; 45 46static 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 58static 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 70static 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 81static 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 95static 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 109static 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 121static 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 */