apple-efuses.c (1794B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Apple SoC eFuse driver 4 * 5 * Copyright (C) The Asahi Linux Contributors 6 */ 7 8#include <linux/io.h> 9#include <linux/mod_devicetable.h> 10#include <linux/module.h> 11#include <linux/nvmem-provider.h> 12#include <linux/platform_device.h> 13 14struct apple_efuses_priv { 15 void __iomem *fuses; 16}; 17 18static int apple_efuses_read(void *context, unsigned int offset, void *val, 19 size_t bytes) 20{ 21 struct apple_efuses_priv *priv = context; 22 u32 *dst = val; 23 24 while (bytes >= sizeof(u32)) { 25 *dst++ = readl_relaxed(priv->fuses + offset); 26 bytes -= sizeof(u32); 27 offset += sizeof(u32); 28 } 29 30 return 0; 31} 32 33static int apple_efuses_probe(struct platform_device *pdev) 34{ 35 struct apple_efuses_priv *priv; 36 struct resource *res; 37 struct nvmem_config config = { 38 .dev = &pdev->dev, 39 .read_only = true, 40 .reg_read = apple_efuses_read, 41 .stride = sizeof(u32), 42 .word_size = sizeof(u32), 43 .name = "apple_efuses_nvmem", 44 .id = NVMEM_DEVID_AUTO, 45 .root_only = true, 46 }; 47 48 priv = devm_kzalloc(config.dev, sizeof(*priv), GFP_KERNEL); 49 if (!priv) 50 return -ENOMEM; 51 52 priv->fuses = devm_platform_get_and_ioremap_resource(pdev, 0, &res); 53 if (IS_ERR(priv->fuses)) 54 return PTR_ERR(priv->fuses); 55 56 config.priv = priv; 57 config.size = resource_size(res); 58 59 return PTR_ERR_OR_ZERO(devm_nvmem_register(config.dev, &config)); 60} 61 62static const struct of_device_id apple_efuses_of_match[] = { 63 { .compatible = "apple,efuses", }, 64 {} 65}; 66 67MODULE_DEVICE_TABLE(of, apple_efuses_of_match); 68 69static struct platform_driver apple_efuses_driver = { 70 .driver = { 71 .name = "apple_efuses", 72 .of_match_table = apple_efuses_of_match, 73 }, 74 .probe = apple_efuses_probe, 75}; 76 77module_platform_driver(apple_efuses_driver); 78 79MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>"); 80MODULE_LICENSE("GPL");