0001
0002
0003
0004
0005
0006 #include <linux/io.h>
0007 #include <linux/module.h>
0008 #include <linux/nvmem-provider.h>
0009 #include <linux/of_reserved_mem.h>
0010 #include <linux/platform_device.h>
0011
0012 struct rmem {
0013 struct device *dev;
0014 struct nvmem_device *nvmem;
0015 struct reserved_mem *mem;
0016
0017 phys_addr_t size;
0018 };
0019
0020 static int rmem_read(void *context, unsigned int offset,
0021 void *val, size_t bytes)
0022 {
0023 struct rmem *priv = context;
0024 size_t available = priv->mem->size;
0025 loff_t off = offset;
0026 void *addr;
0027 int count;
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 addr = memremap(priv->mem->base, available, MEMREMAP_WB);
0040 if (IS_ERR(addr)) {
0041 dev_err(priv->dev, "Failed to remap memory region\n");
0042 return PTR_ERR(addr);
0043 }
0044
0045 count = memory_read_from_buffer(val, bytes, &off, addr, available);
0046
0047 memunmap(addr);
0048
0049 return count;
0050 }
0051
0052 static int rmem_probe(struct platform_device *pdev)
0053 {
0054 struct nvmem_config config = { };
0055 struct device *dev = &pdev->dev;
0056 struct reserved_mem *mem;
0057 struct rmem *priv;
0058
0059 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0060 if (!priv)
0061 return -ENOMEM;
0062 priv->dev = dev;
0063
0064 mem = of_reserved_mem_lookup(dev->of_node);
0065 if (!mem) {
0066 dev_err(dev, "Failed to lookup reserved memory\n");
0067 return -EINVAL;
0068 }
0069 priv->mem = mem;
0070
0071 config.dev = dev;
0072 config.priv = priv;
0073 config.name = "rmem";
0074 config.size = mem->size;
0075 config.reg_read = rmem_read;
0076
0077 return PTR_ERR_OR_ZERO(devm_nvmem_register(dev, &config));
0078 }
0079
0080 static const struct of_device_id rmem_match[] = {
0081 { .compatible = "nvmem-rmem", },
0082 { },
0083 };
0084 MODULE_DEVICE_TABLE(of, rmem_match);
0085
0086 static struct platform_driver rmem_driver = {
0087 .probe = rmem_probe,
0088 .driver = {
0089 .name = "rmem",
0090 .of_match_table = rmem_match,
0091 },
0092 };
0093 module_platform_driver(rmem_driver);
0094
0095 MODULE_AUTHOR("Nicolas Saenz Julienne <nsaenzjulienne@suse.de>");
0096 MODULE_DESCRIPTION("Reserved Memory Based nvmem Driver");
0097 MODULE_LICENSE("GPL");