1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2023 Westermo Network Technologies AB 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/platform_device.h> 11 12 struct qoriq_efuse_priv { 13 void __iomem *base; 14 }; 15 16 static int qoriq_efuse_read(void *context, unsigned int offset, void *val, 17 size_t bytes) 18 { 19 struct qoriq_efuse_priv *priv = context; 20 21 /* .stride = 4 so offset is guaranteed to be aligned */ 22 __ioread32_copy(val, priv->base + offset, bytes / 4); 23 24 /* Ignore trailing bytes (there shouldn't be any) */ 25 26 return 0; 27 } 28 29 static int qoriq_efuse_probe(struct platform_device *pdev) 30 { 31 struct nvmem_config config = { 32 .dev = &pdev->dev, 33 .read_only = true, 34 .reg_read = qoriq_efuse_read, 35 .stride = sizeof(u32), 36 .word_size = sizeof(u32), 37 .name = "qoriq_efuse_read", 38 .id = NVMEM_DEVID_AUTO, 39 .root_only = true, 40 }; 41 struct qoriq_efuse_priv *priv; 42 struct nvmem_device *nvmem; 43 struct resource *res; 44 45 priv = devm_kzalloc(config.dev, sizeof(*priv), GFP_KERNEL); 46 if (!priv) 47 return -ENOMEM; 48 49 priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 50 if (IS_ERR(priv->base)) 51 return PTR_ERR(priv->base); 52 53 config.size = resource_size(res); 54 config.priv = priv; 55 nvmem = devm_nvmem_register(config.dev, &config); 56 57 return PTR_ERR_OR_ZERO(nvmem); 58 } 59 60 static const struct of_device_id qoriq_efuse_of_match[] = { 61 { .compatible = "fsl,t1023-sfp", }, 62 {/* sentinel */}, 63 }; 64 MODULE_DEVICE_TABLE(of, qoriq_efuse_of_match); 65 66 static struct platform_driver qoriq_efuse_driver = { 67 .probe = qoriq_efuse_probe, 68 .driver = { 69 .name = "qoriq-efuse", 70 .of_match_table = qoriq_efuse_of_match, 71 }, 72 }; 73 module_platform_driver(qoriq_efuse_driver); 74 75 MODULE_AUTHOR("Richard Alpe <richard.alpe@bit42.se>"); 76 MODULE_DESCRIPTION("NXP QorIQ Security Fuse Processor (SFP) Reader"); 77 MODULE_LICENSE("GPL"); 78