83 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Apple SoC eFuse driver4 *5 * Copyright (C) The Asahi Linux Contributors6 */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 .add_legacy_fixed_of_cells = true,40 .read_only = true,41 .reg_read = apple_efuses_read,42 .stride = sizeof(u32),43 .word_size = sizeof(u32),44 .name = "apple_efuses_nvmem",45 .id = NVMEM_DEVID_AUTO,46 .root_only = true,47 };48 49 priv = devm_kzalloc(config.dev, sizeof(*priv), GFP_KERNEL);50 if (!priv)51 return -ENOMEM;52 53 priv->fuses = devm_platform_get_and_ioremap_resource(pdev, 0, &res);54 if (IS_ERR(priv->fuses))55 return PTR_ERR(priv->fuses);56 57 config.priv = priv;58 config.size = resource_size(res);59 60 return PTR_ERR_OR_ZERO(devm_nvmem_register(config.dev, &config));61}62 63static const struct of_device_id apple_efuses_of_match[] = {64 { .compatible = "apple,efuses", },65 {}66};67 68MODULE_DEVICE_TABLE(of, apple_efuses_of_match);69 70static struct platform_driver apple_efuses_driver = {71 .driver = {72 .name = "apple_efuses",73 .of_match_table = apple_efuses_of_match,74 },75 .probe = apple_efuses_probe,76};77 78module_platform_driver(apple_efuses_driver);79 80MODULE_AUTHOR("Sven Peter <sven@svenpeter.dev>");81MODULE_DESCRIPTION("Apple SoC eFuse driver");82MODULE_LICENSE("GPL");83