.. | .. |
---|
2 | 2 | #ifndef _LINUX_NVRAM_H |
---|
3 | 3 | #define _LINUX_NVRAM_H |
---|
4 | 4 | |
---|
| 5 | +#include <linux/errno.h> |
---|
5 | 6 | #include <uapi/linux/nvram.h> |
---|
6 | 7 | |
---|
7 | | -/* __foo is foo without grabbing the rtc_lock - get it yourself */ |
---|
8 | | -extern unsigned char __nvram_read_byte(int i); |
---|
9 | | -extern unsigned char nvram_read_byte(int i); |
---|
10 | | -extern void __nvram_write_byte(unsigned char c, int i); |
---|
11 | | -extern void nvram_write_byte(unsigned char c, int i); |
---|
12 | | -extern int __nvram_check_checksum(void); |
---|
13 | | -extern int nvram_check_checksum(void); |
---|
| 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 | + |
---|
14 | 133 | #endif /* _LINUX_NVRAM_H */ |
---|