File Index
Files and directories
Sign in
FILE

s32g-ocotp-nvmem.c

File preview with syntax highlighting.

linux-6.19.14/drivers/nvmem/s32g-ocotp-nvmem.c C
  1// SPDX-License-Identifier: GPL-2.0+
  2/*
  3 * Copyright 2023-2025 NXP
  4 */
  5
  6#include <linux/device.h>
  7#include <linux/io.h>
  8#include <linux/module.h>
  9#include <linux/nvmem-provider.h>
 10#include <linux/of.h>
 11#include <linux/of_device.h>
 12#include <linux/platform_device.h>
 13
 14struct s32g_ocotp_priv {
 15	struct device *dev;
 16	void __iomem *base;
 17};
 18
 19static int s32g_ocotp_read(void *context, unsigned int offset,
 20			    void *val, size_t bytes)
 21{
 22	struct s32g_ocotp_priv *s32g_data = context;
 23	u32 *dst = val;
 24
 25	while (bytes >= sizeof(u32)) {
 26		*dst++ = ioread32(s32g_data->base + offset);
 27
 28		bytes -= sizeof(u32);
 29		offset += sizeof(u32);
 30	}
 31
 32	return 0;
 33}
 34
 35static struct nvmem_keepout s32g_keepouts[] = {
 36	{ .start = 0,   .end = 520 },
 37	{ .start = 540, .end = 564 },
 38	{ .start = 596, .end = 664 },
 39	{ .start = 668, .end = 676 },
 40	{ .start = 684, .end = 732 },
 41	{ .start = 744, .end = 864 },
 42	{ .start = 908, .end = 924 },
 43	{ .start = 928, .end = 936 },
 44	{ .start = 948, .end = 964 },
 45	{ .start = 968, .end = 976 },
 46	{ .start = 984, .end = 1012 },
 47};
 48
 49static struct nvmem_config s32g_ocotp_nvmem_config = {
 50	.name = "s32g-ocotp",
 51	.add_legacy_fixed_of_cells = true,
 52	.read_only = true,
 53	.word_size = 4,
 54	.reg_read = s32g_ocotp_read,
 55	.keepout = s32g_keepouts,
 56	.nkeepout = ARRAY_SIZE(s32g_keepouts),
 57};
 58
 59static const struct of_device_id ocotp_of_match[] = {
 60	{ .compatible = "nxp,s32g2-ocotp" },
 61	{ /* sentinel */ }
 62};
 63
 64static int s32g_ocotp_probe(struct platform_device *pdev)
 65{
 66	struct s32g_ocotp_priv *s32g_data;
 67	struct device *dev = &pdev->dev;
 68	struct nvmem_device *nvmem;
 69	struct resource *res;
 70
 71	s32g_data = devm_kzalloc(dev, sizeof(*s32g_data), GFP_KERNEL);
 72	if (!s32g_data)
 73		return -ENOMEM;
 74
 75	s32g_data->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
 76	if (IS_ERR(s32g_data->base))
 77		return dev_err_probe(dev, PTR_ERR(s32g_data->base),
 78				     "Cannot map OCOTP device.\n");
 79
 80	s32g_data->dev = dev;
 81	s32g_ocotp_nvmem_config.dev = dev;
 82	s32g_ocotp_nvmem_config.priv = s32g_data;
 83	s32g_ocotp_nvmem_config.size = resource_size(res);
 84
 85	nvmem = devm_nvmem_register(dev, &s32g_ocotp_nvmem_config);
 86
 87	return PTR_ERR_OR_ZERO(nvmem);
 88}
 89
 90static struct platform_driver s32g_ocotp_driver = {
 91	.probe = s32g_ocotp_probe,
 92	.driver = {
 93		.name = "s32g-ocotp",
 94		.of_match_table = ocotp_of_match,
 95	},
 96};
 97module_platform_driver(s32g_ocotp_driver);
 98MODULE_AUTHOR("NXP");
 99MODULE_DESCRIPTION("S32G OCOTP driver");
100MODULE_LICENSE("GPL");
~/ Read-only file preview.