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