18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _LINUX_NVRAM_H 38c2ecf20Sopenharmony_ci#define _LINUX_NVRAM_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci#include <linux/errno.h> 68c2ecf20Sopenharmony_ci#include <uapi/linux/nvram.h> 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC 98c2ecf20Sopenharmony_ci#include <asm/machdep.h> 108c2ecf20Sopenharmony_ci#endif 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/** 138c2ecf20Sopenharmony_ci * struct nvram_ops - NVRAM functionality made available to drivers 148c2ecf20Sopenharmony_ci * @read: validate checksum (if any) then load a range of bytes from NVRAM 158c2ecf20Sopenharmony_ci * @write: store a range of bytes to NVRAM then update checksum (if any) 168c2ecf20Sopenharmony_ci * @read_byte: load a single byte from NVRAM 178c2ecf20Sopenharmony_ci * @write_byte: store a single byte to NVRAM 188c2ecf20Sopenharmony_ci * @get_size: return the fixed number of bytes in the NVRAM 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * Architectures which provide an nvram ops struct need not implement all 218c2ecf20Sopenharmony_ci * of these methods. If the NVRAM hardware can be accessed only one byte 228c2ecf20Sopenharmony_ci * at a time then it may be sufficient to provide .read_byte and .write_byte. 238c2ecf20Sopenharmony_ci * If the NVRAM has a checksum (and it is to be checked) the .read and 248c2ecf20Sopenharmony_ci * .write methods can be used to implement that efficiently. 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci * Portable drivers may use the wrapper functions defined here. 278c2ecf20Sopenharmony_ci * The nvram_read() and nvram_write() functions call the .read and .write 288c2ecf20Sopenharmony_ci * methods when available and fall back on the .read_byte and .write_byte 298c2ecf20Sopenharmony_ci * methods otherwise. 308c2ecf20Sopenharmony_ci */ 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistruct nvram_ops { 338c2ecf20Sopenharmony_ci ssize_t (*get_size)(void); 348c2ecf20Sopenharmony_ci unsigned char (*read_byte)(int); 358c2ecf20Sopenharmony_ci void (*write_byte)(unsigned char, int); 368c2ecf20Sopenharmony_ci ssize_t (*read)(char *, size_t, loff_t *); 378c2ecf20Sopenharmony_ci ssize_t (*write)(char *, size_t, loff_t *); 388c2ecf20Sopenharmony_ci#if defined(CONFIG_X86) || defined(CONFIG_M68K) 398c2ecf20Sopenharmony_ci long (*initialize)(void); 408c2ecf20Sopenharmony_ci long (*set_checksum)(void); 418c2ecf20Sopenharmony_ci#endif 428c2ecf20Sopenharmony_ci}; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ciextern const struct nvram_ops arch_nvram_ops; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_cistatic inline ssize_t nvram_get_size(void) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC 498c2ecf20Sopenharmony_ci if (ppc_md.nvram_size) 508c2ecf20Sopenharmony_ci return ppc_md.nvram_size(); 518c2ecf20Sopenharmony_ci#else 528c2ecf20Sopenharmony_ci if (arch_nvram_ops.get_size) 538c2ecf20Sopenharmony_ci return arch_nvram_ops.get_size(); 548c2ecf20Sopenharmony_ci#endif 558c2ecf20Sopenharmony_ci return -ENODEV; 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_cistatic inline unsigned char nvram_read_byte(int addr) 598c2ecf20Sopenharmony_ci{ 608c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC 618c2ecf20Sopenharmony_ci if (ppc_md.nvram_read_val) 628c2ecf20Sopenharmony_ci return ppc_md.nvram_read_val(addr); 638c2ecf20Sopenharmony_ci#else 648c2ecf20Sopenharmony_ci if (arch_nvram_ops.read_byte) 658c2ecf20Sopenharmony_ci return arch_nvram_ops.read_byte(addr); 668c2ecf20Sopenharmony_ci#endif 678c2ecf20Sopenharmony_ci return 0xFF; 688c2ecf20Sopenharmony_ci} 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistatic inline void nvram_write_byte(unsigned char val, int addr) 718c2ecf20Sopenharmony_ci{ 728c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC 738c2ecf20Sopenharmony_ci if (ppc_md.nvram_write_val) 748c2ecf20Sopenharmony_ci ppc_md.nvram_write_val(addr, val); 758c2ecf20Sopenharmony_ci#else 768c2ecf20Sopenharmony_ci if (arch_nvram_ops.write_byte) 778c2ecf20Sopenharmony_ci arch_nvram_ops.write_byte(val, addr); 788c2ecf20Sopenharmony_ci#endif 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistatic inline ssize_t nvram_read_bytes(char *buf, size_t count, loff_t *ppos) 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci ssize_t nvram_size = nvram_get_size(); 848c2ecf20Sopenharmony_ci loff_t i; 858c2ecf20Sopenharmony_ci char *p = buf; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci if (nvram_size < 0) 888c2ecf20Sopenharmony_ci return nvram_size; 898c2ecf20Sopenharmony_ci for (i = *ppos; count > 0 && i < nvram_size; ++i, ++p, --count) 908c2ecf20Sopenharmony_ci *p = nvram_read_byte(i); 918c2ecf20Sopenharmony_ci *ppos = i; 928c2ecf20Sopenharmony_ci return p - buf; 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cistatic inline ssize_t nvram_write_bytes(char *buf, size_t count, loff_t *ppos) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci ssize_t nvram_size = nvram_get_size(); 988c2ecf20Sopenharmony_ci loff_t i; 998c2ecf20Sopenharmony_ci char *p = buf; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci if (nvram_size < 0) 1028c2ecf20Sopenharmony_ci return nvram_size; 1038c2ecf20Sopenharmony_ci for (i = *ppos; count > 0 && i < nvram_size; ++i, ++p, --count) 1048c2ecf20Sopenharmony_ci nvram_write_byte(*p, i); 1058c2ecf20Sopenharmony_ci *ppos = i; 1068c2ecf20Sopenharmony_ci return p - buf; 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_cistatic inline ssize_t nvram_read(char *buf, size_t count, loff_t *ppos) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC 1128c2ecf20Sopenharmony_ci if (ppc_md.nvram_read) 1138c2ecf20Sopenharmony_ci return ppc_md.nvram_read(buf, count, ppos); 1148c2ecf20Sopenharmony_ci#else 1158c2ecf20Sopenharmony_ci if (arch_nvram_ops.read) 1168c2ecf20Sopenharmony_ci return arch_nvram_ops.read(buf, count, ppos); 1178c2ecf20Sopenharmony_ci#endif 1188c2ecf20Sopenharmony_ci return nvram_read_bytes(buf, count, ppos); 1198c2ecf20Sopenharmony_ci} 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_cistatic inline ssize_t nvram_write(char *buf, size_t count, loff_t *ppos) 1228c2ecf20Sopenharmony_ci{ 1238c2ecf20Sopenharmony_ci#ifdef CONFIG_PPC 1248c2ecf20Sopenharmony_ci if (ppc_md.nvram_write) 1258c2ecf20Sopenharmony_ci return ppc_md.nvram_write(buf, count, ppos); 1268c2ecf20Sopenharmony_ci#else 1278c2ecf20Sopenharmony_ci if (arch_nvram_ops.write) 1288c2ecf20Sopenharmony_ci return arch_nvram_ops.write(buf, count, ppos); 1298c2ecf20Sopenharmony_ci#endif 1308c2ecf20Sopenharmony_ci return nvram_write_bytes(buf, count, ppos); 1318c2ecf20Sopenharmony_ci} 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci#endif /* _LINUX_NVRAM_H */ 134